diff options
Diffstat (limited to 'src/drivers')
-rw-r--r-- | src/drivers/ipmi/chip.h | 11 | ||||
-rw-r--r-- | src/drivers/ipmi/ipmi_kcs_ops.c | 26 |
2 files changed, 37 insertions, 0 deletions
diff --git a/src/drivers/ipmi/chip.h b/src/drivers/ipmi/chip.h index eb8b4e6d34..1c5afe7b59 100644 --- a/src/drivers/ipmi/chip.h +++ b/src/drivers/ipmi/chip.h @@ -24,6 +24,17 @@ struct drivers_ipmi_config { u8 gpe_interrupt; u8 have_apic; 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_ */ diff --git a/src/drivers/ipmi/ipmi_kcs_ops.c b/src/drivers/ipmi/ipmi_kcs_ops.c index 0cc4e0a965..21102bb74e 100644 --- a/src/drivers/ipmi/ipmi_kcs_ops.c +++ b/src/drivers/ipmi/ipmi_kcs_ops.c @@ -32,6 +32,7 @@ #endif #include <version.h> #include <delay.h> +#include <timer.h> #include "ipmi_kcs.h" #include "chip.h" @@ -62,12 +63,37 @@ static void ipmi_kcs_init(struct device *dev) { struct ipmi_devid_rsp rsp; uint32_t man_id = 0, prod_id = 0; + struct drivers_ipmi_config *conf = NULL; if (!dev->enabled) 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 */ + 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)) { + /* Queried the IPMI revision from BMC */ ipmi_revision_minor = IPMI_IPMI_VERSION_MINOR(rsp.ipmi_version); ipmi_revision_major = IPMI_IPMI_VERSION_MAJOR(rsp.ipmi_version); |