[Skiboot] [PATCH v2] bt: use the maximum retry count returned by the BMC
Cédric Le Goater
clg at fr.ibm.com
Tue Apr 5 03:07:28 AEST 2016
Hello,
On 04/01/2016 05:14 AM, Stewart Smith wrote:
> Cédric Le Goater <clg at fr.ibm.com> writes:
>> OpenPower systems using a AMI firmware on the BMC have a BT device
>> configured with a capability of '1' maximum retry. The following code
>> is equivalent to what skiboot currently supports but it will now also
>> handle setups of other BT devices, like in qemu or OpenBMC.
>>
>> Signed-off-by: Cédric Le Goater <clg at fr.ibm.com>
>
> Looks good and correct.
>
> Merged to master as of 53402d0.
>
> I gather this gets us closer to being able to run with BT under qemu?
Yes. It has been running for some time now. But clearly, this is not all
in mainline yet.
The BT device and the IPMI backend will be in qemu 2.6.
The activation of this device requires a couple of patches on the qemu
side to populate the platform device tree. devices are specified on the
command line and the guest needs to adapt. skiboot also needs to adapt,
so that's an extra patch.
The qemu powernv platform will take some time to merge. Some patches
have reached 2.6, mostly bug fixes, but the core part is still very
much in its own branch. We should push some more for 2.7. I would love
to get rid of the most conflicting parts, mmu and xics for instance.
It will take time.
As for now, I maintain a 2.6-rc0 branch with a port of powernv, device
tree enhancements for the BT device, and some patches implementing a
pseudo flash controller to be able to use directly a pnor.
If people want to start using it, we could :
1. first, make the port on a recent qemu available, 2.6 seems like a
good target, and check for regressions.
2. then, add the extra patches to use BT/IPMI .
For that, we need to discuss some changes on the skiboot side (see
below). I was not in favor of hardcoding the devices as this is not
the qemu philosophy. I can resend a cleaner patch when 1. is done
3. eventually, add the PNOR support.
Thanks,
C.
>From fcb17f3fe8ab1204739fed6ec52f1118be134cf5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg at fr.ibm.com>
Date: Thu, 12 Nov 2015 17:38:40 +0100
Subject: [PATCH 8/8] plat/qemu: add Open Power devices
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This brings the qemu platform to the level of an Open Power platform.
It adds the BT device used to communicate with the BMC using IPMI
messaging, power_downs and reboots the way openpower systems do, PNOR
suppport, etc.
The qemu platform should probably move to the astbmc directory and use
the common routines.
Signed-off-by: Cédric Le Goater <clg at fr.ibm.com>
---
platforms/qemu/qemu.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 143 insertions(+)
Index: skiboot.git/platforms/qemu/qemu.c
===================================================================
--- skiboot.git.orig/platforms/qemu/qemu.c
+++ skiboot.git/platforms/qemu/qemu.c
@@ -21,6 +21,61 @@
#include <console.h>
#include <opal.h>
#include <psi.h>
+#include <bt.h>
+#include <errorlog.h>
+#include <ipmi.h>
+#include <ast.h>
+
+/* BT config */
+#define BT_IO_BASE 0xe4
+#define BT_IO_COUNT 3
+#define BT_LPC_IRQ 10
+
+static void qemu_ipmi_error(struct ipmi_msg *msg)
+{
+ prlog(PR_DEBUG, "QEMU: error sending msg. cc = %02x\n", msg->cc);
+
+ ipmi_free_msg(msg);
+}
+
+static void qemu_ipmi_setenables(void)
+{
+ struct ipmi_msg *msg;
+
+ struct {
+ uint8_t oem2_en : 1;
+ uint8_t oem1_en : 1;
+ uint8_t oem0_en : 1;
+ uint8_t reserved : 1;
+ uint8_t sel_en : 1;
+ uint8_t msgbuf_en : 1;
+ uint8_t msgbuf_full_int_en : 1;
+ uint8_t rxmsg_queue_int_en : 1;
+ } data;
+
+ memset(&data, 0, sizeof(data));
+
+ /* The spec says we need to read-modify-write to not clobber
+ * the state of the other flags. These are set on by the bmc */
+ data.rxmsg_queue_int_en = 1;
+ data.sel_en = 1;
+
+ /* These are the ones we want to set on */
+ data.msgbuf_en = 1;
+
+ msg = ipmi_mkmsg_simple(IPMI_SET_ENABLES, &data, sizeof(data));
+ if (!msg) {
+ prlog(PR_ERR, "QEMU: failed to set enables\n");
+ return;
+ }
+
+ msg->error = qemu_ipmi_error;
+
+ ipmi_queue_msg(msg);
+
+}
+
+extern int pnor_init(void);
static void qemu_init(void)
{
@@ -28,10 +83,58 @@ static void qemu_init(void)
if (!dummy_console_enabled())
uart_setup_opal_console();
+ /* Initialize PNOR/NVRAM */
+ pnor_init();
+
/* Setup LPC RTC and use it as time source. Call after
* chiptod_init()
*/
lpc_rtc_init();
+
+ bt_init();
+ ipmi_sel_init();
+ ipmi_wdt_init();
+ ipmi_fru_init(0);
+ ipmi_opal_init();
+ elog_init();
+ ipmi_sensor_init();
+
+ /* As soon as IPMI is up, inform BMC we are in "S0" */
+ ipmi_set_power_state(IPMI_PWR_SYS_S0_WORKING, IPMI_PWR_NOCHANGE);
+
+ /* Enable IPMI OEM message interrupts */
+ qemu_ipmi_setenables();
+
+ ipmi_set_fw_progress_sensor(IPMI_FW_MOTHERBOARD_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, "ipmi-bt")) {
+ prlog(PR_WARNING, "QEMU: bt device already here\n");
+ 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)
@@ -53,6 +156,14 @@ static void qemu_dt_fixup_uart(struct dt
#define UART_IO_COUNT 8
#define UART_LPC_IRQ 4
+ /* First check if the BT interface is already there */
+ dt_for_each_child(lpc, uart) {
+ if (dt_node_is_compatible(uart, "pnpPNP,501")) {
+ prlog(PR_WARNING, "QEMU: uart device already here\n");
+ return;
+ }
+ }
+
snprintf(namebuf, sizeof(namebuf), "serial at i%x", UART_IO_BASE);
uart = dt_new(lpc, namebuf);
@@ -84,6 +195,14 @@ static void qemu_dt_fixup_rtc(struct dt_
struct dt_node *rtc;
char namebuf[32];
+ /* First check if the BT interface is already there */
+ dt_for_each_child(lpc, rtc) {
+ if (dt_node_is_compatible(rtc, "pnpPNP,b00")) {
+ prlog(PR_WARNING, "QEMU: rtc device already here\n");
+ return;
+ }
+ }
+
/*
* Follows the structure expected by the kernel file
* arch/powerpc/sysdev/rtc_cmos_setup.c
@@ -113,6 +232,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 +240,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"))
@@ -130,6 +265,9 @@ static bool qemu_probe(void)
psi_set_external_irq_policy(EXTERNAL_IRQ_POLICY_SKIBOOT);
+ /* Initialize AHB accesses via AST2400 */
+ ast_io_init();
+
/*
* Setup UART and use it as console. For now, we
* don't expose the interrupt as we know it's not
@@ -145,4 +283,9 @@ 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,
+ .start_preload_resource = flash_start_preload_resource,
+ .resource_loaded = flash_resource_loaded,
+ .terminate = ipmi_terminate,
};
More information about the Skiboot
mailing list