aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Stanley <joel@jms.id.au>2015-02-27 16:12:01 +1030
committerJeremy Kerr <jk@ozlabs.org>2015-03-04 16:02:20 +0800
commita736f60aaed6bb33047646949df7ab08697a896c (patch)
tree8be60781340c7a0d64e4d7f91491f356325ff731
parent573d0a9af9e46afbefc34cf95510f3d91bc778f6 (diff)
downloadskiboot-a736f60aaed6bb33047646949df7ab08697a896c.zip
skiboot-a736f60aaed6bb33047646949df7ab08697a896c.tar.gz
skiboot-a736f60aaed6bb33047646949df7ab08697a896c.tar.bz2
hw/ipmi: Set boot count sensor
The boot count sensor is a discrete sensor that is set once the system is up and running. On successful boot, the BMC expects the sensor to be set to 2. Signed-off-by: Joel Stanley <joel@jms.id.au>
-rw-r--r--core/ipmi.c9
-rw-r--r--hw/ipmi/ipmi-sensor.c30
-rw-r--r--include/ipmi.h3
3 files changed, 36 insertions, 6 deletions
diff --git a/core/ipmi.c b/core/ipmi.c
index 6c1179f..78a54de 100644
--- a/core/ipmi.c
+++ b/core/ipmi.c
@@ -156,9 +156,14 @@ static void ipmi_get_message_flags_complete(struct ipmi_msg *msg)
/* Once we see an interrupt we assume the payload has
* booted. We disable the wdt and let the OS setup its own
- * wdt. */
- if (flags & IPMI_MESSAGE_FLAGS_WATCHDOG_PRE_TIMEOUT)
+ * wdt.
+ *
+ * This is also where we consider the OS to be booted, so we set
+ * the boot count sensor */
+ if (flags & IPMI_MESSAGE_FLAGS_WATCHDOG_PRE_TIMEOUT) {
ipmi_wdt_stop();
+ ipmi_set_boot_count();
+ }
/* Message available in the event buffer? Queue a Read Event command
* to retrieve it. The flag is cleared by performing a read */
diff --git a/hw/ipmi/ipmi-sensor.c b/hw/ipmi/ipmi-sensor.c
index 9b08d30..cdaf5fb 100644
--- a/hw/ipmi/ipmi-sensor.c
+++ b/hw/ipmi/ipmi-sensor.c
@@ -20,11 +20,12 @@
#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 IPMI_WRITE_SENSOR (1 << 1)
+#define IPMI_SET_ASSERTION (1 << 5)
+#define IPMI_ASSERTION_STATE(state) (1 << state)
-#define FW_PROGRESS_SENSOR 0x0F
+#define FW_PROGRESS_SENSOR 0x0F
+#define BOOT_COUNT_SENSOR 0xAA
/* Ghetto. TODO: Do something smarter */
int16_t sensors[255];
@@ -35,6 +36,27 @@ struct set_sensor_req {
u8 reading[8];
};
+int ipmi_set_boot_count(void)
+{
+ struct set_sensor_req req;
+ struct ipmi_msg *msg;
+
+ memset(&req, 0, sizeof(req));
+
+ req.sensor = BOOT_COUNT_SENSOR;
+ /* Set assertion bit */
+ req.operation = IPMI_SET_ASSERTION;
+ /* Set state 2 */
+ req.reading[1] = IPMI_ASSERTION_STATE(2);
+
+ /* We just need the first 4 bytes */
+ msg = ipmi_mkmsg_simple(IPMI_SET_SENSOR_READING, &req, 4);
+ if (!msg)
+ return OPAL_HARDWARE;
+
+ return ipmi_queue_msg(msg);
+}
+
int ipmi_set_fw_progress_sensor(uint8_t state)
{
int fw_sensor_id = sensors[FW_PROGRESS_SENSOR];
diff --git a/include/ipmi.h b/include/ipmi.h
index c078471..77e4b9a 100644
--- a/include/ipmi.h
+++ b/include/ipmi.h
@@ -253,4 +253,7 @@ void ipmi_wdt_final_reset(void);
/* Discover id of settable ipmi sensors */
void ipmi_sensor_init(void);
+/* Set the boot count once the OS is up and running */
+int ipmi_set_boot_count(void);
+
#endif