aboutsummaryrefslogtreecommitdiff
path: root/platforms/astbmc
diff options
context:
space:
mode:
authorSamuel Mendoza-Jonas <sam@mendozajonas.com>2019-05-09 13:08:40 +1000
committerOliver O'Halloran <oohall@gmail.com>2019-05-09 15:06:39 +1000
commit1bc63b896405ccea4584d764a28d01858e81efc3 (patch)
tree8cae38af94a430224e8c2fbff5afc40f7cc5c63f /platforms/astbmc
parentbc2b1de3beb2ee7904d936b10c8a57cd220d8ddc (diff)
downloadskiboot-1bc63b896405ccea4584d764a28d01858e81efc3.zip
skiboot-1bc63b896405ccea4584d764a28d01858e81efc3.tar.gz
skiboot-1bc63b896405ccea4584d764a28d01858e81efc3.tar.bz2
platforms/astbmc: Check for SBE validation step
On some POWER8 astbmc systems an update to the SBE requires pausing at runtime to ensure integrity of the SBE. If this is required the BMC will set a chassis boot option IPMI flag using the OEM parameter 0x62. If Skiboot sees this flag is set it waits until the SBE update is complete and the flag is cleared. Unfortunately the mystery operation that validates the SBE also leaves it in a bad state and unable to be used for timer operations. To workaround this the flag is checked as soon as possible (ie. when IPMI and the console are set up), and once complete the system is rebooted. Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com> Reviewed-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Reviewed-by: Andrew Jeffery <andrew@aj.id.au> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Diffstat (limited to 'platforms/astbmc')
-rw-r--r--platforms/astbmc/astbmc.h1
-rw-r--r--platforms/astbmc/common.c64
-rw-r--r--platforms/astbmc/garrison.c1
-rw-r--r--platforms/astbmc/habanero.c1
-rw-r--r--platforms/astbmc/p8dnu.c1
-rw-r--r--platforms/astbmc/p8dtu.c2
6 files changed, 70 insertions, 0 deletions
diff --git a/platforms/astbmc/astbmc.h b/platforms/astbmc/astbmc.h
index fe358b7..c302b60 100644
--- a/platforms/astbmc/astbmc.h
+++ b/platforms/astbmc/astbmc.h
@@ -103,6 +103,7 @@ extern void astbmc_ext_irq_serirq_cpld(unsigned int chip_id);
extern int pnor_init(void);
extern void check_all_slot_table(void);
extern void astbmc_exit(void);
+extern void astbmc_seeprom_update(void);
extern void slot_table_init(const struct slot_table_entry *top_table);
extern void slot_table_get_slot_info(struct phb *phb, struct pci_device * pd);
diff --git a/platforms/astbmc/common.c b/platforms/astbmc/common.c
index faa73e2..76fa25f 100644
--- a/platforms/astbmc/common.c
+++ b/platforms/astbmc/common.c
@@ -26,6 +26,7 @@
#include <bt.h>
#include <errorlog.h>
#include <lpc.h>
+#include <timebase.h>
#include "astbmc.h"
@@ -168,6 +169,69 @@ int64_t astbmc_ipmi_reboot(void)
return ipmi_chassis_control(IPMI_CHASSIS_HARD_RESET);
}
+void astbmc_seeprom_update(void)
+{
+ int flag_set, counter, rc;
+
+ rc = ipmi_get_chassis_boot_opt_request();
+
+ if (rc) {
+ prlog(PR_WARNING, "Failed to check SBE validation flag\n");
+ return;
+ }
+
+ flag_set = ipmi_chassis_check_sbe_validation();
+
+ if (flag_set <= 0) {
+ prlog(PR_DEBUG, "SBE validation flag unset or invalid\n");
+ return;
+ }
+
+ /*
+ * Flag is set, wait until SBE validation is complete and the flag
+ * has been reset.
+ */
+ prlog(PR_WARNING, "SBE validation required, waiting for completion\n");
+ prlog(PR_WARNING, "System will be powered off if validation fails\n");
+ counter = 0;
+
+ while (flag_set > 0) {
+ time_wait_ms(10000);
+ if (++counter % 3 == 0) {
+ /* Let the user know we're alive every 30s */
+ prlog(PR_WARNING, "waiting for completion...\n");
+ }
+ if (counter == 180) {
+ /* This is longer than expected and we have no way of
+ * checking if it's still running. Apologies if you
+ * ever see this message.
+ */
+ prlog(PR_WARNING, "30 minutes has elapsed, this is longer than expected for verification\n");
+ prlog(PR_WARNING, "If no progress is made a power reset of the BMC and Host may be required\n");
+ counter = 0;
+ }
+
+ /* As above, loop anyway if we fail to check the flag */
+ rc = ipmi_get_chassis_boot_opt_request();
+ if (rc == 0)
+ flag_set = ipmi_chassis_check_sbe_validation();
+ else
+ prlog(PR_WARNING, "Failed to check SBE validation flag\n");
+ }
+
+ /*
+ * The SBE validation can (will) leave the SBE in a bad state,
+ * preventing timers from working properly. Reboot so that we
+ * can boot normally with everything intact.
+ */
+ prlog(PR_WARNING, "SBE validation complete, rebooting\n");
+ if (platform.cec_reboot)
+ platform.cec_reboot();
+ else
+ abort();
+ while(true);
+}
+
static void astbmc_fixup_dt_system_id(void)
{
/* Make sure we don't already have one */
diff --git a/platforms/astbmc/garrison.c b/platforms/astbmc/garrison.c
index 5cbe64b..ddd3372 100644
--- a/platforms/astbmc/garrison.c
+++ b/platforms/astbmc/garrison.c
@@ -305,4 +305,5 @@ DECLARE_PLATFORM(garrison) = {
.resource_loaded = flash_resource_loaded,
.exit = ipmi_wdt_final_reset,
.terminate = ipmi_terminate,
+ .seeprom_update = astbmc_seeprom_update,
};
diff --git a/platforms/astbmc/habanero.c b/platforms/astbmc/habanero.c
index 8e11b81..ab01027 100644
--- a/platforms/astbmc/habanero.c
+++ b/platforms/astbmc/habanero.c
@@ -149,4 +149,5 @@ DECLARE_PLATFORM(habanero) = {
.resource_loaded = flash_resource_loaded,
.exit = ipmi_wdt_final_reset,
.terminate = ipmi_terminate,
+ .seeprom_update = astbmc_seeprom_update,
};
diff --git a/platforms/astbmc/p8dnu.c b/platforms/astbmc/p8dnu.c
index 9d42fc4..391aa7a 100644
--- a/platforms/astbmc/p8dnu.c
+++ b/platforms/astbmc/p8dnu.c
@@ -361,4 +361,5 @@ DECLARE_PLATFORM(p8dnu) = {
.resource_loaded = flash_resource_loaded,
.exit = ipmi_wdt_final_reset,
.terminate = ipmi_terminate,
+ .seeprom_update = astbmc_seeprom_update,
};
diff --git a/platforms/astbmc/p8dtu.c b/platforms/astbmc/p8dtu.c
index 69500ea..6f66dc2 100644
--- a/platforms/astbmc/p8dtu.c
+++ b/platforms/astbmc/p8dtu.c
@@ -262,6 +262,7 @@ DECLARE_PLATFORM(p8dtu1u) = {
.resource_loaded = flash_resource_loaded,
.exit = ipmi_wdt_final_reset,
.terminate = ipmi_terminate,
+ .seeprom_update = astbmc_seeprom_update,
};
DECLARE_PLATFORM(p8dtu2u) = {
@@ -279,5 +280,6 @@ DECLARE_PLATFORM(p8dtu2u) = {
.resource_loaded = flash_resource_loaded,
.exit = ipmi_wdt_final_reset,
.terminate = ipmi_terminate,
+ .seeprom_update = astbmc_seeprom_update,
};