[Skiboot] [RFC PATCH] Enable PLDM by default and select it dynamically
Nicholas Piggin
npiggin at gmail.com
Mon May 19 12:11:21 AEST 2025
This is an initial hack at enabling PLDM by default and selecting
between it and IPMI at boot time depending on detected capabilities.
Not tested at all.
Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
Makefile | 2 +-
core/init.c | 31 ++++++++++++++----------------
core/pldm/pldm-mctp.c | 9 +++++++++
hw/ast-bmc/ast-mctp.c | 40 +++++++++++++++++++++++++++++----------
hw/bt.c | 10 ++++++----
include/ast.h | 11 +++++++++++
include/bt.h | 2 +-
include/pldm.h | 9 +++++++++
platforms/astbmc/astbmc.h | 1 -
platforms/astbmc/common.c | 40 +++++++++++++++++++++++++++++++--------
platforms/qemu/qemu.c | 17 +++++++++--------
11 files changed, 122 insertions(+), 50 deletions(-)
diff --git a/Makefile b/Makefile
index 03a0a8773..d67413926 100644
--- a/Makefile
+++ b/Makefile
@@ -62,7 +62,7 @@ CONFIG_FSP?=1
# Try to build without POWER8 support
CONFIG_P8?=1
# Try to build without PLDM code
-CONFIG_PLDM?=0
+CONFIG_PLDM?=1
#
# Where is the source directory, must be a full path (no ~)
diff --git a/core/init.c b/core/init.c
index fae6ec62f..dc369c517 100644
--- a/core/init.c
+++ b/core/init.c
@@ -563,12 +563,11 @@ void __noreturn load_and_boot_kernel(bool is_reboot)
trustedboot_exit_boot_services();
-#ifdef CONFIG_PLDM
- pldm_platform_send_progress_state_change(
- PLDM_STATE_SET_BOOT_PROG_STATE_STARTING_OP_SYS);
-#else
- ipmi_set_fw_progress_sensor(IPMI_FW_OS_BOOT);
-#endif
+ if (use_pldm())
+ pldm_platform_send_progress_state_change(
+ PLDM_STATE_SET_BOOT_PROG_STATE_STARTING_OP_SYS);
+ else
+ ipmi_set_fw_progress_sensor(IPMI_FW_OS_BOOT);
if (!is_reboot) {
/* We wait for the nvram read to complete here so we can
@@ -1413,19 +1412,17 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)
/* Setup ibm,firmware-versions if able */
if (platform.bmc) {
flash_dt_add_fw_version();
-#ifdef CONFIG_PLDM
- pldm_fru_dt_add_bmc_version();
-#else
- ipmi_dt_add_bmc_info();
-#endif
+ if (use_pldm())
+ pldm_fru_dt_add_bmc_version();
+ else
+ ipmi_dt_add_bmc_info();
}
-#ifdef CONFIG_PLDM
- pldm_platform_send_progress_state_change(
- PLDM_STATE_SET_BOOT_PROG_STATE_PCI_RESORUCE_CONFIG);
-#else
- ipmi_set_fw_progress_sensor(IPMI_FW_PCI_INIT);
-#endif
+ if (use_pldm())
+ pldm_platform_send_progress_state_change(
+ PLDM_STATE_SET_BOOT_PROG_STATE_PCI_RESORUCE_CONFIG);
+ else
+ ipmi_set_fw_progress_sensor(IPMI_FW_PCI_INIT);
/*
* These last few things must be done as late as possible
diff --git a/core/pldm/pldm-mctp.c b/core/pldm/pldm-mctp.c
index fb7d8a1cb..a0f62e41b 100644
--- a/core/pldm/pldm-mctp.c
+++ b/core/pldm/pldm-mctp.c
@@ -72,6 +72,13 @@ out:
return rc;
}
+static bool using_pldm;
+
+bool use_pldm(void)
+{
+ return using_pldm;
+}
+
int pldm_mctp_init(void)
{
int nbr_elt = 8, rc = OPAL_SUCCESS;
@@ -108,6 +115,8 @@ int pldm_mctp_init(void)
}
}
+ using_pldm = true;
+
out:
prlog(PR_NOTICE, "%s - done, rc: %d\n", __func__, rc);
return rc;
diff --git a/hw/ast-bmc/ast-mctp.c b/hw/ast-bmc/ast-mctp.c
index 22578e0a5..0d07abd0d 100644
--- a/hw/ast-bmc/ast-mctp.c
+++ b/hw/ast-bmc/ast-mctp.c
@@ -32,6 +32,16 @@ static struct lock mctp_lock = LOCK_UNLOCKED;
#define KCS_STATUS_BMC_READY 0x80
#define KCS_STATUS_OBF 0x01
+/*
+ * Current OpenBMC systems put the MCTP buffer 1MB down from
+ * the end of the LPC FW range.
+ *
+ * The size of the FW range is: 0x1000_0000 so the window be at:
+ *
+ * 0x1000_0000 - 2**20 == 0xff00000
+ */
+#define MCTP_FW_ADDR 0xff00000
+
#define HOST_MAX_INCOMING_MESSAGE_ALLOCATION 131072
#define DESIRED_MTU 32768
@@ -170,15 +180,7 @@ static int astlpc_binding(void)
if (!ops_data)
return OPAL_NO_MEM;
- /*
- * Current OpenBMC systems put the MCTP buffer 1MB down from
- * the end of the LPC FW range.
- *
- * The size of the FW range is: 0x1000_0000 so the window be at:
- *
- * 0x1000_0000 - 2**20 == 0xff00000
- */
- ops_data->lpc_fw_addr = 0xff00000;
+ ops_data->lpc_fw_addr = MCTP_FW_ADDR;
/* values chosen by the OpenBMC driver */
ops_data->kcs_data_addr = KCS_DATA_REG;
@@ -306,6 +308,24 @@ static void message_rx(uint8_t eid, bool tag_owner,
}
}
+#define ASTLPC_MCTP_MAGIC 0x4d435450
+
+bool ast_mctp_available(void)
+{
+ uint32_t data;
+
+ if (!dt_find_compatible_node(dt_root, NULL, "mctp"))
+ return false;
+ if (lpc_probe_read(OPAL_LPC_IO, KCS_STATUS_REG, &data, 1))
+ return false;
+ if (lpc_probe_read(OPAL_LPC_FW, MCTP_FW_ADDR, &data, 4))
+ return false;
+ if (data != cpu_to_be32(ASTLPC_MCTP_MAGIC))
+ return false;
+
+ return true;
+}
+
/*
* Initialize mctp binding for hbrt and provide interfaces for sending
* and receiving mctp messages.
@@ -315,9 +335,9 @@ int ast_mctp_init(void)
uint32_t kcs_serial_irq;
struct dt_node *n;
- /* Search mctp node */
n = dt_find_compatible_node(dt_root, NULL, "mctp");
if (!n) {
+ /* Caller should have checked available already */
prlog(PR_ERR, "No MCTP device\n");
return OPAL_PARAMETER;
}
diff --git a/hw/bt.c b/hw/bt.c
index b41e5ab81..ee7c8893b 100644
--- a/hw/bt.c
+++ b/hw/bt.c
@@ -678,7 +678,7 @@ static struct lpc_client bt_lpc_client = {
.interrupt = bt_irq,
};
-void bt_init(void)
+int bt_init(void)
{
struct dt_node *n;
const struct dt_property *prop;
@@ -695,18 +695,18 @@ void bt_init(void)
n = dt_find_compatible_node(dt_root, NULL, "ipmi-bt");
if (!n) {
prerror("No BT device\n");
- return;
+ return OPAL_PARAMETER;
}
/* Get IO base */
prop = dt_find_property(n, "reg");
if (!prop) {
prerror("Can't find reg property\n");
- return;
+ return OPAL_PARAMETER;
}
if (dt_property_get_cell(prop, 0) != OPAL_LPC_IO) {
prerror("Only supports IO addresses\n");
- return;
+ return OPAL_PARAMETER;
}
bt.base_addr = dt_property_get_cell(prop, 1);
init_timer(&bt.poller, bt_poll, NULL);
@@ -743,4 +743,6 @@ void bt_init(void)
get_bt_caps();
prlog(PR_DEBUG, "Using LPC IRQ %d\n", irq);
+
+ return OPAL_SUCCESS;
}
diff --git a/include/ast.h b/include/ast.h
index 71237fbb7..ef7f5c81f 100644
--- a/include/ast.h
+++ b/include/ast.h
@@ -24,6 +24,9 @@
/* LPC registers */
#define LPC_BASE 0x1e789000
+#define LPC_HICR4 (LPC_BASE + 0x10)
+#define LPC_HICR4_BT_ENABLE (1 << 0)
+#define LPC_HICR4_KCS_ENABLE (1 << 2)
#define LPC_HICR6 (LPC_BASE + 0x80)
#define LPC_HICR7 (LPC_BASE + 0x88)
#define LPC_HICR8 (LPC_BASE + 0x8c)
@@ -116,6 +119,14 @@ enum mctp_msg_type {
int ast_mctp_message_tx(bool tag_owner, uint8_t msg_tag,
uint8_t *msg, int msg_len);
+#ifdef CONFIG_PLDM
+bool ast_mctp_available(void);
+#else
+static inline bool ast_mctp_available(void)
+{
+ return false;
+}
+#endif
int ast_mctp_init(void);
void ast_mctp_exit(void);
diff --git a/include/bt.h b/include/bt.h
index dd2e7b65a..b9932cf76 100644
--- a/include/bt.h
+++ b/include/bt.h
@@ -5,6 +5,6 @@
#define __BT_H
/* Initialise the BT interface */
-void bt_init(void);
+int bt_init(void);
#endif
diff --git a/include/pldm.h b/include/pldm.h
index 54c9bd4bc..a11885ca2 100644
--- a/include/pldm.h
+++ b/include/pldm.h
@@ -8,6 +8,15 @@
#include <skiboot.h>
#include <pldm/include/libpldm/state_set.h>
+#ifdef CONFIG_PLDM
+bool use_pldm(void);
+#else
+static inline bool use_pldm(void)
+{
+ return false;
+}
+#endif
+
/**
* Handle PLDM messages received from MCTP
*/
diff --git a/platforms/astbmc/astbmc.h b/platforms/astbmc/astbmc.h
index 7783fe20c..c9bba3a81 100644
--- a/platforms/astbmc/astbmc.h
+++ b/platforms/astbmc/astbmc.h
@@ -97,7 +97,6 @@ extern void astbmc_early_init(void);
extern int64_t astbmc_ipmi_reboot(void);
extern int64_t astbmc_ipmi_power_down(uint64_t request);
#ifdef CONFIG_PLDM
-extern int astbmc_pldm_init(void);
extern int pnor_pldm_init(void);
#endif
extern void astbmc_init(void);
diff --git a/platforms/astbmc/common.c b/platforms/astbmc/common.c
index 8d1ceb921..6e15baf4e 100644
--- a/platforms/astbmc/common.c
+++ b/platforms/astbmc/common.c
@@ -137,9 +137,9 @@ static int astbmc_fru_init(void)
return 0;
}
-#ifdef CONFIG_PLDM
-int astbmc_pldm_init(void)
+static int astbmc_pldm_init(void)
{
+#ifdef CONFIG_PLDM
int rc = OPAL_SUCCESS;
/* PLDM over MCTP */
@@ -165,16 +165,22 @@ int astbmc_pldm_init(void)
prlog(PR_WARNING, "Failed to configure PLDM\n");
return rc;
-}
+#else
+ assert(0); /* Not reached */
#endif
+}
-void astbmc_init(void)
+static int astbmc_ipmi_init(void)
{
+ int rc;
+
/* Register the BT interface with the IPMI layer
*
* Initialise this first to enable PNOR access
*/
- bt_init();
+ rc = bt_init();
+ if (rc)
+ return rc;
/* Initialize PNOR/NVRAM */
pnor_init();
@@ -201,6 +207,24 @@ void astbmc_init(void)
/* Setup UART console for use by Linux via OPAL API */
set_opal_console(&uart_opal_con);
+
+ return OPAL_SUCCESS;
+}
+
+void astbmc_init(void)
+{
+ prlog(PR_ERR, "PLAT: Checking platform management\n");
+ if (ast_mctp_available()) {
+ if (astbmc_pldm_init() == OPAL_SUCCESS) {
+ prlog(PR_NOTICE, "PLAT: Using PLDM for platform management\n");
+ return;
+ }
+ }
+ if (astbmc_ipmi_init() == OPAL_SUCCESS) {
+ prlog(PR_NOTICE, "PLAT: Using IPMI for platform management\n");
+ return;
+ }
+ prlog(PR_ERR, "PLAT: Unable to initialise platform management\n");
}
int64_t astbmc_ipmi_power_down(uint64_t request)
@@ -600,9 +624,9 @@ void astbmc_early_init(void)
void astbmc_exit(void)
{
-#ifdef CONFIG_PLDM
- return;
-#endif
+ if (use_pldm())
+ return;
+
ipmi_wdt_final_reset();
ipmi_set_boot_count();
diff --git a/platforms/qemu/qemu.c b/platforms/qemu/qemu.c
index c6c6a5007..d40e8381a 100644
--- a/platforms/qemu/qemu.c
+++ b/platforms/qemu/qemu.c
@@ -10,6 +10,7 @@
#include <platforms/astbmc/astbmc.h>
static bool bt_device_present;
+static bool kcs_device_present;
ST_PLUGGABLE(qemu_slot0, "pcie.0");
ST_PLUGGABLE(qemu_slot1, "pcie.1");
@@ -51,6 +52,11 @@ static bool qemu_probe_common(const char *compat)
bt_device_present = true;
}
+ /* check if the KCS device was defined by QEMU */
+ dt_for_each_compatible(dt_root, n, "kcs") {
+ kcs_device_present = true;
+ }
+
slot_table_init(qemu_phb_table);
return true;
@@ -83,15 +89,10 @@ static bool qemu_probe_powernv11(void)
static void qemu_init(void)
{
- if (!bt_device_present) {
- set_opal_console(&uart_opal_con);
- } else {
-#ifdef CONFIG_PLDM
- /* need to be checked according platform: P10, P11 ... */
- astbmc_pldm_init();
-#else
+ if (bt_device_present || kcs_device_present) {
astbmc_init();
-#endif
+ } else {
+ set_opal_console(&uart_opal_con);
}
}
--
2.47.1
More information about the Skiboot
mailing list