[Skiboot] [RFC PATCH] plat/qemu: Add BT device

Cédric Le Goater clg at fr.ibm.com
Fri Nov 13 04:23:07 AEDT 2015


This adds the BT device used to communicate with the BMC. This is
sufficient to handle IPMI messaging, power_downs and reboots the
way openpower systems do it.

This patch needs to run on Ben's tree adding the support for the
PowerNV platform in qemu, plus some patches of mine. You will find
the resulting tree here :

	https://github.com/legoater/qemu/tree/powernv

It's basic, probably a little too hacky, but it does provide enough
of a framework to handle communication with the BMC. Is it something
we want to add to qemu ? 

Comments welcome.

Thanks,

C.


Signed-off-by: Cédric Le Goater <clg at fr.ibm.com>
---
 hw/bt.c               |    8 +++++++
 platforms/qemu/qemu.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)

Index: skiboot.git/platforms/qemu/qemu.c
===================================================================
--- skiboot.git.orig/platforms/qemu/qemu.c
+++ skiboot.git/platforms/qemu/qemu.c
@@ -21,6 +21,13 @@
 #include <console.h>
 #include <opal.h>
 #include <psi.h>
+#include <bt.h>
+#include <ipmi.h>
+
+/* BT config */
+#define BT_IO_BASE	0xe4
+#define BT_IO_COUNT	3
+#define BT_LPC_IRQ	10
 
 static void qemu_init(void)
 {
@@ -32,6 +39,33 @@ static void qemu_init(void)
 	 * chiptod_init()
 	 */
 	lpc_rtc_init();
+	bt_init();
+}
+
+static void qemu_dt_fixup_bt(struct dt_node *lpc)
+{
+	struct dt_node *bt;
+	char namebuf[32];
+
+	/* First check if the BT interface is already there */
+	dt_for_each_child(lpc, bt) {
+		if (dt_node_is_compatible(bt, "bt"))
+			return;
+	}
+
+	snprintf(namebuf, sizeof(namebuf), "ipmi-bt at i%x", BT_IO_BASE);
+	bt = dt_new(lpc, namebuf);
+
+	dt_add_property_cells(bt, "reg",
+			      1, /* IO space */
+			      BT_IO_BASE, BT_IO_COUNT);
+	dt_add_property_strings(bt, "compatible", "ipmi-bt");
+
+	/* Mark it as reserved to avoid Linux trying to claim it */
+	dt_add_property_strings(bt, "status", "reserved");
+
+	dt_add_property_cells(bt, "interrupts", BT_LPC_IRQ);
+	dt_add_property_cells(bt, "interrupt-parent", lpc->phandle);
 }
 
 static void qemu_dt_fixup_uart(struct dt_node *lpc)
@@ -113,6 +147,7 @@ static void qemu_dt_fixup(void)
 
 	qemu_dt_fixup_rtc(primary_lpc);
 	qemu_dt_fixup_uart(primary_lpc);
+	qemu_dt_fixup_bt(primary_lpc);
 }
 
 static void qemu_ext_irq_serirq_cpld(unsigned int chip_id)
@@ -120,6 +155,21 @@ static void qemu_ext_irq_serirq_cpld(uns
 	lpc_all_interrupts(chip_id);
 }
 
+static int64_t qemu_ipmi_power_down(uint64_t request)
+{
+	if (request != IPMI_CHASSIS_PWR_DOWN) {
+		prlog(PR_WARNING, "PLAT: unexpected shutdown request %llx\n",
+				   request);
+	}
+
+	return ipmi_chassis_control(request);
+}
+
+static int64_t qemu_ipmi_reboot(void)
+{
+	return ipmi_chassis_control(IPMI_CHASSIS_HARD_RESET);
+}
+
 static bool qemu_probe(void)
 {
 	if (!dt_node_is_compatible(dt_root, "qemu,powernv"))
@@ -145,4 +195,7 @@ DECLARE_PLATFORM(qemu) = {
 	.probe		= qemu_probe,
 	.init		= qemu_init,
 	.external_irq   = qemu_ext_irq_serirq_cpld,
+	.cec_power_down = qemu_ipmi_power_down,
+	.cec_reboot     = qemu_ipmi_reboot,
+	.terminate	= ipmi_terminate,
 };



More information about the Skiboot mailing list