summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/ipmi/chip.h11
-rw-r--r--src/drivers/ipmi/ipmi_kcs_ops.c26
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);