aboutsummaryrefslogtreecommitdiff
path: root/hw/ipmi
diff options
context:
space:
mode:
authorJoel Stanley <joel@jms.id.au>2014-09-24 14:44:20 +1000
committerJeremy Kerr <jk@ozlabs.org>2015-03-04 16:02:20 +0800
commit81791e5da50b9804a19f2bfbc25916791b28d499 (patch)
treec6a4922b4a687f9353c7246cb9bab6b7712c6f52 /hw/ipmi
parent0f2343075276a6bcc15c679b4270d0843e002da0 (diff)
downloadskiboot-81791e5da50b9804a19f2bfbc25916791b28d499.zip
skiboot-81791e5da50b9804a19f2bfbc25916791b28d499.tar.gz
skiboot-81791e5da50b9804a19f2bfbc25916791b28d499.tar.bz2
hw/ipmi: Add API for setting sensors
This allows setting a given IPMI sensor to a given value. There are helpers for setting the firmware boot progress that will be used for updating the BMC with the host boot progress. The sensor ids are parsed from the device tree. If the sensor cannot be found we will silently continue. Signed-off-by: Joel Stanley <joel@jms.id.au>
Diffstat (limited to 'hw/ipmi')
-rw-r--r--hw/ipmi/Makefile.inc3
-rw-r--r--hw/ipmi/ipmi-sensor.c102
2 files changed, 104 insertions, 1 deletions
diff --git a/hw/ipmi/Makefile.inc b/hw/ipmi/Makefile.inc
index 1c358a9..06cdc96 100644
--- a/hw/ipmi/Makefile.inc
+++ b/hw/ipmi/Makefile.inc
@@ -1,6 +1,7 @@
SUBDIRS += hw/ipmi
IPMI_OBJS = ipmi-rtc.o ipmi-power.o ipmi-opal.o ipmi-fru.o ipmi-sel.o
-IPMI_OBJS += ipmi-watchdog.o
+IPMI_OBJS += ipmi-watchdog.o ipmi-sensor.o
+
IPMI = hw/ipmi/built-in.o
$(IPMI): $(IPMI_OBJS:%=hw/ipmi/%)
diff --git a/hw/ipmi/ipmi-sensor.c b/hw/ipmi/ipmi-sensor.c
new file mode 100644
index 0000000..9b08d30
--- /dev/null
+++ b/hw/ipmi/ipmi-sensor.c
@@ -0,0 +1,102 @@
+/* Copyright 2013-2014 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <device.h>
+#include <ipmi.h>
+#include <opal.h>
+#include <skiboot.h>
+#include <string.h>
+
+/* This field controls whether the sensor reading byte is written or left
+ * unchanged according to the sensor */
+#define IPMI_WRITE_SENSOR 0x01
+
+#define FW_PROGRESS_SENSOR 0x0F
+
+/* Ghetto. TODO: Do something smarter */
+int16_t sensors[255];
+
+struct set_sensor_req {
+ u8 sensor;
+ u8 operation;
+ u8 reading[8];
+};
+
+int ipmi_set_fw_progress_sensor(uint8_t state)
+{
+ int fw_sensor_id = sensors[FW_PROGRESS_SENSOR];
+
+ if (fw_sensor_id < 0) {
+ prlog(PR_DEBUG, "SENSOR: fw progress set but not present\n");
+ return OPAL_HARDWARE;
+ }
+
+ return ipmi_set_sensor(fw_sensor_id, &state, sizeof(state));
+}
+
+int ipmi_set_sensor(uint8_t sensor, uint8_t *reading, size_t len)
+{
+ struct ipmi_msg *msg;
+ struct set_sensor_req request;
+
+ if (!ipmi_present())
+ return OPAL_CLOSED;
+
+ if (len > 8) {
+ prlog(PR_ERR, "IPMI: sensor setting length %zd invalid\n",
+ len);
+ return OPAL_PARAMETER;
+ }
+
+ memset(&request, 0, sizeof(request));
+
+ request.sensor = sensor;
+ request.operation = IPMI_WRITE_SENSOR;
+ memcpy(request.reading, reading, len);
+
+ prlog(PR_INFO, "IPMI: setting sensor %02x to %02x ...\n",
+ request.sensor, request.reading[0]);
+
+ /* Send the minimial length message: header plus the reading bytes */
+ msg = ipmi_mkmsg_simple(IPMI_SET_SENSOR_READING, &request, len + 2);
+ if (!msg)
+ return OPAL_HARDWARE;
+
+ return ipmi_queue_msg(msg);
+}
+
+void ipmi_sensor_init(void)
+{
+ struct dt_node *n;
+ const struct dt_property *type, *num;
+
+ memset(sensors, -1, sizeof(sensors));
+
+ dt_for_each_compatible(dt_root, n, "ibm,ipmi-sensor") {
+ type = dt_find_property(n, "ipmi-sensor-type");
+ if (!type) {
+ prerror("IPMI: sensor doesn't have ipmi-sensor-type\n");
+ continue;
+ }
+
+ num = dt_find_property(n, "reg");
+ if (!num) {
+ prerror("IPMI: sensor doesn't have reg property\n");
+ continue;
+ }
+ sensors[(uint8_t)num->prop[0]] = type->prop[0];
+ }
+}