diff mbox series

[V2,15/15] platforms/astbmc: Enable PLDM support

Message ID 20220429094744.72855-16-clombard@linux.vnet.ibm.com
State Superseded
Headers show
Series Complete PLDM responder and enable PLDM support | expand

Commit Message

Christophe Lombard April 29, 2022, 9:47 a.m. UTC
Last BMC firmware is available with a complete PLDM support on Rainier
system.
This patch allows initially to:
- Initialize the MCTP core.
- Enable the mctp binding over LPC bus interface and new wrappers to send
and receive PLDM messages over the mctp library.
- Retrieve all needed PLDM data.
- "Virtualize" the content of a BMC flash based on lid files.

Then, others mandatory support (watchdog, opal rtc, opal ipmi) are enabled.

Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
---
 core/init.c                | 22 +++++++++++++++++++++-
 core/pldm/pldm-common.c    | 11 +++++++++++
 include/pldm.h             |  2 ++
 platforms/astbmc/astbmc.h  |  4 ++++
 platforms/astbmc/common.c  | 37 +++++++++++++++++++++++++++++++++++++
 platforms/astbmc/pnor.c    | 25 +++++++++++++++++++++++++
 platforms/astbmc/rainier.c | 33 +++++++++++++++++++++++++++++----
 7 files changed, 129 insertions(+), 5 deletions(-)

Comments

Frederic Barrat April 26, 2023, 3:26 p.m. UTC | #1
On 29/04/2022 11:47, Christophe Lombard wrote:
> Last BMC firmware is available with a complete PLDM support on Rainier
> system.
> This patch allows initially to:
> - Initialize the MCTP core.
> - Enable the mctp binding over LPC bus interface and new wrappers to send
> and receive PLDM messages over the mctp library.
> - Retrieve all needed PLDM data.
> - "Virtualize" the content of a BMC flash based on lid files.
> 
> Then, others mandatory support (watchdog, opal rtc, opal ipmi) are enabled.
> 
> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
> ---
>   core/init.c                | 22 +++++++++++++++++++++-
>   core/pldm/pldm-common.c    | 11 +++++++++++
>   include/pldm.h             |  2 ++
>   platforms/astbmc/astbmc.h  |  4 ++++
>   platforms/astbmc/common.c  | 37 +++++++++++++++++++++++++++++++++++++
>   platforms/astbmc/pnor.c    | 25 +++++++++++++++++++++++++
>   platforms/astbmc/rainier.c | 33 +++++++++++++++++++++++++++++----
>   7 files changed, 129 insertions(+), 5 deletions(-)
> 
> diff --git a/core/init.c b/core/init.c
> index a1fd5f2b..f8492e2d 100644
> --- a/core/init.c
> +++ b/core/init.c
> @@ -34,6 +34,7 @@
>   #include <libfdt/libfdt.h>
>   #include <timer.h>
>   #include <ipmi.h>
> +#include <pldm.h>
>   #include <sensor.h>
>   #include <xive.h>
>   #include <nvram.h>
> @@ -561,8 +562,15 @@ void __noreturn load_and_boot_kernel(bool is_reboot)
>   
>   	trustedboot_exit_boot_services();
>   
> +#ifdef CONFIG_PLDM
> +	if (pldm_present())
> +		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);


Not specific to this patch, but for all the cases where we try PLDM 
first and fall back in IPMI: I'm wondering how this is going to age and 
whether we should go full PLDM or nothing. Are we sure we're not going 
to end up in some weird state where some of the config is PLDM and some 
is IPMI?

   Fred

> +#else
>   	ipmi_set_fw_progress_sensor(IPMI_FW_OS_BOOT);
> -
> +#endif
>   
>   	if (!is_reboot) {
>   		/* We wait for the nvram read to complete here so we can
> @@ -1372,10 +1380,22 @@ 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
>   	}
>   
> +#ifdef CONFIG_PLDM
> +	if (pldm_present())
> +		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);
> +#else
>   	ipmi_set_fw_progress_sensor(IPMI_FW_PCI_INIT);
> +#endif
>   
>   	/*
>   	 * These last few things must be done as late as possible
> diff --git a/core/pldm/pldm-common.c b/core/pldm/pldm-common.c
> index 50f86948..42bce415 100644
> --- a/core/pldm/pldm-common.c
> +++ b/core/pldm/pldm-common.c
> @@ -10,6 +10,13 @@
>   #include <ast.h>
>   #include "pldm.h"
>   
> +bool pldm_enabled;
> +
> +bool pldm_present(void)
> +{
> +	return pldm_enabled;
> +}
> +
>   /*
>    * Print content of PLDM message in hex mode.
>    * 15 bytes per line.
> @@ -136,6 +143,8 @@ int pldm_mctp_init(void)
>   		goto out;
>   	}
>   
> +	pldm_enabled = true;
> +
>   	/* Get PDRs data */
>   	rc = pldm_platform_init();
>   	if (rc) {
> @@ -162,6 +171,8 @@ out:
>   
>   void pldm_mctp_exit(void)
>   {
> +	pldm_enabled = false;
> +
>   	pldm_platform_exit();
>   
>   	ast_mctp_exit();
> diff --git a/include/pldm.h b/include/pldm.h
> index 8a91ee99..7e7e3b93 100644
> --- a/include/pldm.h
> +++ b/include/pldm.h
> @@ -8,6 +8,8 @@
>   #include <skiboot.h>
>   #include <pldm/libpldm/state_set.h>
>   
> +bool pldm_present(void);
> +
>   /**
>    * PLDM over MCTP initialization
>    */
> diff --git a/platforms/astbmc/astbmc.h b/platforms/astbmc/astbmc.h
> index 00f22123..7783fe20 100644
> --- a/platforms/astbmc/astbmc.h
> +++ b/platforms/astbmc/astbmc.h
> @@ -96,6 +96,10 @@ extern const struct bmc_platform bmc_plat_ast2600_openbmc;
>   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);
>   extern void astbmc_ext_irq_serirq_cpld(unsigned int chip_id);
>   extern int pnor_init(void);
> diff --git a/platforms/astbmc/common.c b/platforms/astbmc/common.c
> index 83ef70ad..a6f52a38 100644
> --- a/platforms/astbmc/common.c
> +++ b/platforms/astbmc/common.c
> @@ -9,6 +9,7 @@
>   #include <xscom.h>
>   #include <ast.h>
>   #include <ipmi.h>
> +#include <pldm.h>
>   #include <bt.h>
>   #include <errorlog.h>
>   #include <lpc.h>
> @@ -104,6 +105,38 @@ static int astbmc_fru_init(void)
>   	return 0;
>   }
>   
> +#ifdef CONFIG_PLDM
> +int astbmc_pldm_init(void)
> +{
> +	int rc;
> +
> +	/* PLDM over MCTP */
> +	rc = pldm_mctp_init();
> +	if (rc)
> +		goto err;
> +
> +	/* Initialize PNOR/NVRAM */
> +	rc = pnor_pldm_init();
> +	if (rc)
> +		goto err;
> +
> +	/* Initialize elog */
> +	elog_init();
> +
> +	pldm_watchdog_init();
> +	pldm_rtc_init();
> +	/*pldm_opal_init(); FIXME */
> +
> +	/* Setup UART console for use by Linux via OPAL API */
> +	set_opal_console(&uart_opal_con);
> +
> +	return OPAL_SUCCESS;
> +
> +err:
> +	prlog(PR_WARNING, "Failed to configure PLDM\n");
> +	return rc;
> +}
> +#endif
>   
>   void astbmc_init(void)
>   {
> @@ -501,6 +534,10 @@ void astbmc_early_init(void)
>   
>   void astbmc_exit(void)
>   {
> +#ifdef CONFIG_PLDM
> +	if (pldm_present())
> +		return;
> +#endif
>   	ipmi_wdt_final_reset();
>   }
>   
> diff --git a/platforms/astbmc/pnor.c b/platforms/astbmc/pnor.c
> index 64f2249d..853da467 100644
> --- a/platforms/astbmc/pnor.c
> +++ b/platforms/astbmc/pnor.c
> @@ -5,6 +5,7 @@
>   #include <device.h>
>   #include <console.h>
>   #include <opal.h>
> +#include <pldm.h>
>   #include <libflash/ipmi-hiomap.h>
>   #include <libflash/mbox-flash.h>
>   #include <libflash/libflash.h>
> @@ -32,6 +33,30 @@ static enum ast_flash_style ast_flash_get_fallback_style(void)
>       return raw_mem;
>   }
>   
> +#ifdef CONFIG_PLDM
> +int pnor_pldm_init(void)
> +{
> +	struct blocklevel_device *bl = NULL;
> +	int rc = 0;
> +
> +	rc = pldm_lid_files_init(&bl);
> +	if (rc) {
> +		prerror("PLAT: Failed to init PNOR driver\n");
> +		goto fail;
> +	}
> +
> +	rc = flash_register(bl);
> +	if (!rc)
> +		return 0;
> +
> +fail:
> +	if (bl)
> +		pldm_lid_files_exit(bl);
> +
> +	return rc;
> +}
> +#endif
> +
>   int pnor_init(void)
>   {
>   	struct spi_flash_ctrl *pnor_ctrl = NULL;
> diff --git a/platforms/astbmc/rainier.c b/platforms/astbmc/rainier.c
> index 3e21e1b9..26ce6acf 100644
> --- a/platforms/astbmc/rainier.c
> +++ b/platforms/astbmc/rainier.c
> @@ -6,6 +6,7 @@
>   #include <skiboot.h>
>   #include <device.h>
>   #include <ipmi.h>
> +#include <pldm.h>
>   #include <pau.h>
>   #include <chip.h>
>   #include <i2c.h>
> @@ -321,9 +322,33 @@ static void rainier_pau_create_i2c_bus(void)
>   	}
>   }
>   
> +static int64_t rainier_power_down(uint64_t request)
> +{
> +#ifdef CONFIG_PLDM
> +	/* Issue a PLDM request for a Off-Soft Graceful */
> +	if (pldm_present())
> +		return pldm_platform_power_off();
> +#endif
> +	return astbmc_ipmi_power_down(request);
> +}
> +
> +static int64_t rainier_reboot(void)
> +{
> +#ifdef CONFIG_PLDM
> +	/* Issue a PLDM request for a graceful restart */
> +	if (pldm_present())
> +		return pldm_platform_restart();
> +#endif
> +	return astbmc_ipmi_reboot();
> +}
> +
>   static void rainier_init(void)
>   {
> -	astbmc_init();
> +#ifdef CONFIG_PLDM
> +	if (astbmc_pldm_init())
> +#endif
> +		astbmc_init();
> +
>   	rainier_init_slot_power();
>   }
>   
> @@ -365,9 +390,9 @@ DECLARE_PLATFORM(rainier) = {
>   	.start_preload_resource	= flash_start_preload_resource,
>   	.resource_loaded	= flash_resource_loaded,
>   	.bmc			= &bmc_plat_ast2600_openbmc,
> -	.cec_power_down         = astbmc_ipmi_power_down,
> -	.cec_reboot             = astbmc_ipmi_reboot,
> -	.elog_commit		= ipmi_elog_commit,
> +	.cec_power_down         = rainier_power_down,
> +	.cec_reboot             = rainier_reboot,
> +	.elog_commit		= ipmi_elog_commit, /* FIXME */
>   	.pau_device_detect	= rainier_pau_device_detect,
>   	.ocapi			= &rainier_ocapi,
>   	.exit			= astbmc_exit,
Christophe Lombard May 2, 2023, 3:35 p.m. UTC | #2
Le 26/04/2023 à 17:26, Frederic Barrat a écrit :
>
>
> On 29/04/2022 11:47, Christophe Lombard wrote:
>> Last BMC firmware is available with a complete PLDM support on Rainier
>> system.
>> This patch allows initially to:
>> - Initialize the MCTP core.
>> - Enable the mctp binding over LPC bus interface and new wrappers to 
>> send
>> and receive PLDM messages over the mctp library.
>> - Retrieve all needed PLDM data.
>> - "Virtualize" the content of a BMC flash based on lid files.
>>
>> Then, others mandatory support (watchdog, opal rtc, opal ipmi) are 
>> enabled.
>>
>> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
>> ---
>>   core/init.c                | 22 +++++++++++++++++++++-
>>   core/pldm/pldm-common.c    | 11 +++++++++++
>>   include/pldm.h             |  2 ++
>>   platforms/astbmc/astbmc.h  |  4 ++++
>>   platforms/astbmc/common.c  | 37 +++++++++++++++++++++++++++++++++++++
>>   platforms/astbmc/pnor.c    | 25 +++++++++++++++++++++++++
>>   platforms/astbmc/rainier.c | 33 +++++++++++++++++++++++++++++----
>>   7 files changed, 129 insertions(+), 5 deletions(-)
>>
>> diff --git a/core/init.c b/core/init.c
>> index a1fd5f2b..f8492e2d 100644
>> --- a/core/init.c
>> +++ b/core/init.c
>> @@ -34,6 +34,7 @@
>>   #include <libfdt/libfdt.h>
>>   #include <timer.h>
>>   #include <ipmi.h>
>> +#include <pldm.h>
>>   #include <sensor.h>
>>   #include <xive.h>
>>   #include <nvram.h>
>> @@ -561,8 +562,15 @@ void __noreturn load_and_boot_kernel(bool 
>> is_reboot)
>>         trustedboot_exit_boot_services();
>>   +#ifdef CONFIG_PLDM
>> +    if (pldm_present())
>> +        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);
>
>
> Not specific to this patch, but for all the cases where we try PLDM 
> first and fall back in IPMI: I'm wondering how this is going to age 
> and whether we should go full PLDM or nothing. Are we sure we're not 
> going to end up in some weird state where some of the config is PLDM 
> and some is IPMI?
>
>   Fred
>

Normally we shouldn't have a hybrid state where one part of skiboot uses 
pdlm and the other ipmi.
The idea is only in case of pldm issue, we switch completely to IPMI

>> +#else
>>       ipmi_set_fw_progress_sensor(IPMI_FW_OS_BOOT);
>> -
>> +#endif
>>         if (!is_reboot) {
>>           /* We wait for the nvram read to complete here so we can
>> @@ -1372,10 +1380,22 @@ 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
>>       }
>>   +#ifdef CONFIG_PLDM
>> +    if (pldm_present())
>> +        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);
>> +#else
>>       ipmi_set_fw_progress_sensor(IPMI_FW_PCI_INIT);
>> +#endif
>>         /*
>>        * These last few things must be done as late as possible
>> diff --git a/core/pldm/pldm-common.c b/core/pldm/pldm-common.c
>> index 50f86948..42bce415 100644
>> --- a/core/pldm/pldm-common.c
>> +++ b/core/pldm/pldm-common.c
>> @@ -10,6 +10,13 @@
>>   #include <ast.h>
>>   #include "pldm.h"
>>   +bool pldm_enabled;
>> +
>> +bool pldm_present(void)
>> +{
>> +    return pldm_enabled;
>> +}
>> +
>>   /*
>>    * Print content of PLDM message in hex mode.
>>    * 15 bytes per line.
>> @@ -136,6 +143,8 @@ int pldm_mctp_init(void)
>>           goto out;
>>       }
>>   +    pldm_enabled = true;
>> +
>>       /* Get PDRs data */
>>       rc = pldm_platform_init();
>>       if (rc) {
>> @@ -162,6 +171,8 @@ out:
>>     void pldm_mctp_exit(void)
>>   {
>> +    pldm_enabled = false;
>> +
>>       pldm_platform_exit();
>>         ast_mctp_exit();
>> diff --git a/include/pldm.h b/include/pldm.h
>> index 8a91ee99..7e7e3b93 100644
>> --- a/include/pldm.h
>> +++ b/include/pldm.h
>> @@ -8,6 +8,8 @@
>>   #include <skiboot.h>
>>   #include <pldm/libpldm/state_set.h>
>>   +bool pldm_present(void);
>> +
>>   /**
>>    * PLDM over MCTP initialization
>>    */
>> diff --git a/platforms/astbmc/astbmc.h b/platforms/astbmc/astbmc.h
>> index 00f22123..7783fe20 100644
>> --- a/platforms/astbmc/astbmc.h
>> +++ b/platforms/astbmc/astbmc.h
>> @@ -96,6 +96,10 @@ extern const struct bmc_platform 
>> bmc_plat_ast2600_openbmc;
>>   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);
>>   extern void astbmc_ext_irq_serirq_cpld(unsigned int chip_id);
>>   extern int pnor_init(void);
>> diff --git a/platforms/astbmc/common.c b/platforms/astbmc/common.c
>> index 83ef70ad..a6f52a38 100644
>> --- a/platforms/astbmc/common.c
>> +++ b/platforms/astbmc/common.c
>> @@ -9,6 +9,7 @@
>>   #include <xscom.h>
>>   #include <ast.h>
>>   #include <ipmi.h>
>> +#include <pldm.h>
>>   #include <bt.h>
>>   #include <errorlog.h>
>>   #include <lpc.h>
>> @@ -104,6 +105,38 @@ static int astbmc_fru_init(void)
>>       return 0;
>>   }
>>   +#ifdef CONFIG_PLDM
>> +int astbmc_pldm_init(void)
>> +{
>> +    int rc;
>> +
>> +    /* PLDM over MCTP */
>> +    rc = pldm_mctp_init();
>> +    if (rc)
>> +        goto err;
>> +
>> +    /* Initialize PNOR/NVRAM */
>> +    rc = pnor_pldm_init();
>> +    if (rc)
>> +        goto err;
>> +
>> +    /* Initialize elog */
>> +    elog_init();
>> +
>> +    pldm_watchdog_init();
>> +    pldm_rtc_init();
>> +    /*pldm_opal_init(); FIXME */
>> +
>> +    /* Setup UART console for use by Linux via OPAL API */
>> +    set_opal_console(&uart_opal_con);
>> +
>> +    return OPAL_SUCCESS;
>> +
>> +err:
>> +    prlog(PR_WARNING, "Failed to configure PLDM\n");
>> +    return rc;
>> +}
>> +#endif
>>     void astbmc_init(void)
>>   {
>> @@ -501,6 +534,10 @@ void astbmc_early_init(void)
>>     void astbmc_exit(void)
>>   {
>> +#ifdef CONFIG_PLDM
>> +    if (pldm_present())
>> +        return;
>> +#endif
>>       ipmi_wdt_final_reset();
>>   }
>>   diff --git a/platforms/astbmc/pnor.c b/platforms/astbmc/pnor.c
>> index 64f2249d..853da467 100644
>> --- a/platforms/astbmc/pnor.c
>> +++ b/platforms/astbmc/pnor.c
>> @@ -5,6 +5,7 @@
>>   #include <device.h>
>>   #include <console.h>
>>   #include <opal.h>
>> +#include <pldm.h>
>>   #include <libflash/ipmi-hiomap.h>
>>   #include <libflash/mbox-flash.h>
>>   #include <libflash/libflash.h>
>> @@ -32,6 +33,30 @@ static enum ast_flash_style 
>> ast_flash_get_fallback_style(void)
>>       return raw_mem;
>>   }
>>   +#ifdef CONFIG_PLDM
>> +int pnor_pldm_init(void)
>> +{
>> +    struct blocklevel_device *bl = NULL;
>> +    int rc = 0;
>> +
>> +    rc = pldm_lid_files_init(&bl);
>> +    if (rc) {
>> +        prerror("PLAT: Failed to init PNOR driver\n");
>> +        goto fail;
>> +    }
>> +
>> +    rc = flash_register(bl);
>> +    if (!rc)
>> +        return 0;
>> +
>> +fail:
>> +    if (bl)
>> +        pldm_lid_files_exit(bl);
>> +
>> +    return rc;
>> +}
>> +#endif
>> +
>>   int pnor_init(void)
>>   {
>>       struct spi_flash_ctrl *pnor_ctrl = NULL;
>> diff --git a/platforms/astbmc/rainier.c b/platforms/astbmc/rainier.c
>> index 3e21e1b9..26ce6acf 100644
>> --- a/platforms/astbmc/rainier.c
>> +++ b/platforms/astbmc/rainier.c
>> @@ -6,6 +6,7 @@
>>   #include <skiboot.h>
>>   #include <device.h>
>>   #include <ipmi.h>
>> +#include <pldm.h>
>>   #include <pau.h>
>>   #include <chip.h>
>>   #include <i2c.h>
>> @@ -321,9 +322,33 @@ static void rainier_pau_create_i2c_bus(void)
>>       }
>>   }
>>   +static int64_t rainier_power_down(uint64_t request)
>> +{
>> +#ifdef CONFIG_PLDM
>> +    /* Issue a PLDM request for a Off-Soft Graceful */
>> +    if (pldm_present())
>> +        return pldm_platform_power_off();
>> +#endif
>> +    return astbmc_ipmi_power_down(request);
>> +}
>> +
>> +static int64_t rainier_reboot(void)
>> +{
>> +#ifdef CONFIG_PLDM
>> +    /* Issue a PLDM request for a graceful restart */
>> +    if (pldm_present())
>> +        return pldm_platform_restart();
>> +#endif
>> +    return astbmc_ipmi_reboot();
>> +}
>> +
>>   static void rainier_init(void)
>>   {
>> -    astbmc_init();
>> +#ifdef CONFIG_PLDM
>> +    if (astbmc_pldm_init())
>> +#endif
>> +        astbmc_init();
>> +
>>       rainier_init_slot_power();
>>   }
>>   @@ -365,9 +390,9 @@ DECLARE_PLATFORM(rainier) = {
>>       .start_preload_resource    = flash_start_preload_resource,
>>       .resource_loaded    = flash_resource_loaded,
>>       .bmc            = &bmc_plat_ast2600_openbmc,
>> -    .cec_power_down         = astbmc_ipmi_power_down,
>> -    .cec_reboot             = astbmc_ipmi_reboot,
>> -    .elog_commit        = ipmi_elog_commit,
>> +    .cec_power_down         = rainier_power_down,
>> +    .cec_reboot             = rainier_reboot,
>> +    .elog_commit        = ipmi_elog_commit, /* FIXME */
>>       .pau_device_detect    = rainier_pau_device_detect,
>>       .ocapi            = &rainier_ocapi,
>>       .exit            = astbmc_exit,
diff mbox series

Patch

diff --git a/core/init.c b/core/init.c
index a1fd5f2b..f8492e2d 100644
--- a/core/init.c
+++ b/core/init.c
@@ -34,6 +34,7 @@ 
 #include <libfdt/libfdt.h>
 #include <timer.h>
 #include <ipmi.h>
+#include <pldm.h>
 #include <sensor.h>
 #include <xive.h>
 #include <nvram.h>
@@ -561,8 +562,15 @@  void __noreturn load_and_boot_kernel(bool is_reboot)
 
 	trustedboot_exit_boot_services();
 
+#ifdef CONFIG_PLDM
+	if (pldm_present())
+		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);
+#else
 	ipmi_set_fw_progress_sensor(IPMI_FW_OS_BOOT);
-
+#endif
 
 	if (!is_reboot) {
 		/* We wait for the nvram read to complete here so we can
@@ -1372,10 +1380,22 @@  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
 	}
 
+#ifdef CONFIG_PLDM
+	if (pldm_present())
+		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);
+#else
 	ipmi_set_fw_progress_sensor(IPMI_FW_PCI_INIT);
+#endif
 
 	/*
 	 * These last few things must be done as late as possible
diff --git a/core/pldm/pldm-common.c b/core/pldm/pldm-common.c
index 50f86948..42bce415 100644
--- a/core/pldm/pldm-common.c
+++ b/core/pldm/pldm-common.c
@@ -10,6 +10,13 @@ 
 #include <ast.h>
 #include "pldm.h"
 
+bool pldm_enabled;
+
+bool pldm_present(void)
+{
+	return pldm_enabled;
+}
+
 /*
  * Print content of PLDM message in hex mode.
  * 15 bytes per line.
@@ -136,6 +143,8 @@  int pldm_mctp_init(void)
 		goto out;
 	}
 
+	pldm_enabled = true;
+
 	/* Get PDRs data */
 	rc = pldm_platform_init();
 	if (rc) {
@@ -162,6 +171,8 @@  out:
 
 void pldm_mctp_exit(void)
 {
+	pldm_enabled = false;
+
 	pldm_platform_exit();
 
 	ast_mctp_exit();
diff --git a/include/pldm.h b/include/pldm.h
index 8a91ee99..7e7e3b93 100644
--- a/include/pldm.h
+++ b/include/pldm.h
@@ -8,6 +8,8 @@ 
 #include <skiboot.h>
 #include <pldm/libpldm/state_set.h>
 
+bool pldm_present(void);
+
 /**
  * PLDM over MCTP initialization
  */
diff --git a/platforms/astbmc/astbmc.h b/platforms/astbmc/astbmc.h
index 00f22123..7783fe20 100644
--- a/platforms/astbmc/astbmc.h
+++ b/platforms/astbmc/astbmc.h
@@ -96,6 +96,10 @@  extern const struct bmc_platform bmc_plat_ast2600_openbmc;
 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);
 extern void astbmc_ext_irq_serirq_cpld(unsigned int chip_id);
 extern int pnor_init(void);
diff --git a/platforms/astbmc/common.c b/platforms/astbmc/common.c
index 83ef70ad..a6f52a38 100644
--- a/platforms/astbmc/common.c
+++ b/platforms/astbmc/common.c
@@ -9,6 +9,7 @@ 
 #include <xscom.h>
 #include <ast.h>
 #include <ipmi.h>
+#include <pldm.h>
 #include <bt.h>
 #include <errorlog.h>
 #include <lpc.h>
@@ -104,6 +105,38 @@  static int astbmc_fru_init(void)
 	return 0;
 }
 
+#ifdef CONFIG_PLDM
+int astbmc_pldm_init(void)
+{
+	int rc;
+
+	/* PLDM over MCTP */
+	rc = pldm_mctp_init();
+	if (rc)
+		goto err;
+
+	/* Initialize PNOR/NVRAM */
+	rc = pnor_pldm_init();
+	if (rc)
+		goto err;
+
+	/* Initialize elog */
+	elog_init();
+
+	pldm_watchdog_init();
+	pldm_rtc_init();
+	/*pldm_opal_init(); FIXME */
+
+	/* Setup UART console for use by Linux via OPAL API */
+	set_opal_console(&uart_opal_con);
+
+	return OPAL_SUCCESS;
+
+err:
+	prlog(PR_WARNING, "Failed to configure PLDM\n");
+	return rc;
+}
+#endif
 
 void astbmc_init(void)
 {
@@ -501,6 +534,10 @@  void astbmc_early_init(void)
 
 void astbmc_exit(void)
 {
+#ifdef CONFIG_PLDM
+	if (pldm_present())
+		return;
+#endif
 	ipmi_wdt_final_reset();
 }
 
diff --git a/platforms/astbmc/pnor.c b/platforms/astbmc/pnor.c
index 64f2249d..853da467 100644
--- a/platforms/astbmc/pnor.c
+++ b/platforms/astbmc/pnor.c
@@ -5,6 +5,7 @@ 
 #include <device.h>
 #include <console.h>
 #include <opal.h>
+#include <pldm.h>
 #include <libflash/ipmi-hiomap.h>
 #include <libflash/mbox-flash.h>
 #include <libflash/libflash.h>
@@ -32,6 +33,30 @@  static enum ast_flash_style ast_flash_get_fallback_style(void)
     return raw_mem;
 }
 
+#ifdef CONFIG_PLDM
+int pnor_pldm_init(void)
+{
+	struct blocklevel_device *bl = NULL;
+	int rc = 0;
+
+	rc = pldm_lid_files_init(&bl);
+	if (rc) {
+		prerror("PLAT: Failed to init PNOR driver\n");
+		goto fail;
+	}
+
+	rc = flash_register(bl);
+	if (!rc)
+		return 0;
+
+fail:
+	if (bl)
+		pldm_lid_files_exit(bl);
+
+	return rc;
+}
+#endif
+
 int pnor_init(void)
 {
 	struct spi_flash_ctrl *pnor_ctrl = NULL;
diff --git a/platforms/astbmc/rainier.c b/platforms/astbmc/rainier.c
index 3e21e1b9..26ce6acf 100644
--- a/platforms/astbmc/rainier.c
+++ b/platforms/astbmc/rainier.c
@@ -6,6 +6,7 @@ 
 #include <skiboot.h>
 #include <device.h>
 #include <ipmi.h>
+#include <pldm.h>
 #include <pau.h>
 #include <chip.h>
 #include <i2c.h>
@@ -321,9 +322,33 @@  static void rainier_pau_create_i2c_bus(void)
 	}
 }
 
+static int64_t rainier_power_down(uint64_t request)
+{
+#ifdef CONFIG_PLDM
+	/* Issue a PLDM request for a Off-Soft Graceful */
+	if (pldm_present())
+		return pldm_platform_power_off();
+#endif
+	return astbmc_ipmi_power_down(request);
+}
+
+static int64_t rainier_reboot(void)
+{
+#ifdef CONFIG_PLDM
+	/* Issue a PLDM request for a graceful restart */
+	if (pldm_present())
+		return pldm_platform_restart();
+#endif
+	return astbmc_ipmi_reboot();
+}
+
 static void rainier_init(void)
 {
-	astbmc_init();
+#ifdef CONFIG_PLDM
+	if (astbmc_pldm_init())
+#endif
+		astbmc_init();
+
 	rainier_init_slot_power();
 }
 
@@ -365,9 +390,9 @@  DECLARE_PLATFORM(rainier) = {
 	.start_preload_resource	= flash_start_preload_resource,
 	.resource_loaded	= flash_resource_loaded,
 	.bmc			= &bmc_plat_ast2600_openbmc,
-	.cec_power_down         = astbmc_ipmi_power_down,
-	.cec_reboot             = astbmc_ipmi_reboot,
-	.elog_commit		= ipmi_elog_commit,
+	.cec_power_down         = rainier_power_down,
+	.cec_reboot             = rainier_reboot,
+	.elog_commit		= ipmi_elog_commit, /* FIXME */
 	.pau_device_detect	= rainier_pau_device_detect,
 	.ocapi			= &rainier_ocapi,
 	.exit			= astbmc_exit,