drivers/ipmi: Add option to wait for BMC
The BMC on Supermicro X11SSH takes 34 seconds to start the IPMI KCS, but the default timeout of the IPMI KCS code is just 100 msec. Add a configurable timeout option to wait for the BMC to become ready. As it only should boot very long after power on reset, it's not a problem on reset or warm boot. Tested on Supermicro X11SSH. The IPMI driver doesn't fail with a time-out any more. Change-Id: I22c6885eae6fd7c778ac37b18f95b8775e9064e3 Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/34569 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
This commit is contained in:
parent
6276dfee51
commit
3d41a13990
|
@ -24,6 +24,17 @@ struct drivers_ipmi_config {
|
||||||
u8 gpe_interrupt;
|
u8 gpe_interrupt;
|
||||||
u8 have_apic;
|
u8 have_apic;
|
||||||
u32 apic_interrupt;
|
u32 apic_interrupt;
|
||||||
|
/*
|
||||||
|
* Wait for BMC to boot.
|
||||||
|
* This can be used if the BMC takes a long time to boot after PoR:
|
||||||
|
* AST2400 on Supermicro X11SSH: 34 s
|
||||||
|
*/
|
||||||
|
bool wait_for_bmc;
|
||||||
|
/*
|
||||||
|
* The timeout in seconds to wait for the IPMI service to be loaded.
|
||||||
|
* Will be used if wait_for_bmc is true.
|
||||||
|
*/
|
||||||
|
u16 bmc_boot_timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _IMPI_CHIP_H_ */
|
#endif /* _IMPI_CHIP_H_ */
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
#include <delay.h>
|
#include <delay.h>
|
||||||
|
#include <timer.h>
|
||||||
#include "ipmi_kcs.h"
|
#include "ipmi_kcs.h"
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
|
||||||
|
@ -62,12 +63,37 @@ static void ipmi_kcs_init(struct device *dev)
|
||||||
{
|
{
|
||||||
struct ipmi_devid_rsp rsp;
|
struct ipmi_devid_rsp rsp;
|
||||||
uint32_t man_id = 0, prod_id = 0;
|
uint32_t man_id = 0, prod_id = 0;
|
||||||
|
struct drivers_ipmi_config *conf = NULL;
|
||||||
|
|
||||||
if (!dev->enabled)
|
if (!dev->enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "IPMI: PNP KCS 0x%x\n", dev->path.pnp.port);
|
||||||
|
|
||||||
|
if (dev->chip_info)
|
||||||
|
conf = dev->chip_info;
|
||||||
|
|
||||||
/* Get IPMI version for ACPI and SMBIOS */
|
/* Get IPMI version for ACPI and SMBIOS */
|
||||||
|
if (conf && conf->wait_for_bmc && conf->bmc_boot_timeout) {
|
||||||
|
struct stopwatch sw;
|
||||||
|
stopwatch_init_msecs_expire(&sw, conf->bmc_boot_timeout * 1000);
|
||||||
|
printk(BIOS_DEBUG, "IPMI: Waiting for BMC...\n");
|
||||||
|
|
||||||
|
while (!stopwatch_expired(&sw)) {
|
||||||
|
if (inb(dev->path.pnp.port) != 0xff)
|
||||||
|
break;
|
||||||
|
mdelay(100);
|
||||||
|
}
|
||||||
|
if (stopwatch_expired(&sw)) {
|
||||||
|
printk(BIOS_INFO, "IPMI: Waiting for BMC timed out\n");
|
||||||
|
/* Don't write tables if communication failed */
|
||||||
|
dev->enabled = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!ipmi_get_device_id(dev, &rsp)) {
|
if (!ipmi_get_device_id(dev, &rsp)) {
|
||||||
|
/* Queried the IPMI revision from BMC */
|
||||||
ipmi_revision_minor = IPMI_IPMI_VERSION_MINOR(rsp.ipmi_version);
|
ipmi_revision_minor = IPMI_IPMI_VERSION_MINOR(rsp.ipmi_version);
|
||||||
ipmi_revision_major = IPMI_IPMI_VERSION_MAJOR(rsp.ipmi_version);
|
ipmi_revision_major = IPMI_IPMI_VERSION_MAJOR(rsp.ipmi_version);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue