summaryrefslogtreecommitdiffstats
path: root/platforms
diff options
context:
space:
mode:
authorAndrew Jeffery <andrew@aj.id.au>2018-07-17 11:32:53 +0930
committerStewart Smith <stewart@linux.ibm.com>2018-07-17 01:13:16 -0500
commitebc8524a3a457f73083d984296bfd797940a711c (patch)
treeb478552a2b810ceff3e98bbefe67aa07706dbf48 /platforms
parent8972e44f97883e5aabf4b9c6737dcf3b22fd24b8 (diff)
downloadblackbird-skiboot-ebc8524a3a457f73083d984296bfd797940a711c.tar.gz
blackbird-skiboot-ebc8524a3a457f73083d984296bfd797940a711c.zip
ast-io: Rework setup/tear-down of communication with the BMC
It's possible for the platform to configure the BMC with SuperIO access disabled. Rework the interfaces to report failures if SuperIO is not enabled, and clean up once we're finished. Signed-off-by: Andrew Jeffery <andrew@aj.id.au> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'platforms')
-rw-r--r--platforms/astbmc/astbmc.h1
-rw-r--r--platforms/astbmc/common.c112
-rw-r--r--platforms/astbmc/romulus.c2
-rw-r--r--platforms/astbmc/witherspoon.c3
-rw-r--r--platforms/qemu/qemu.c4
5 files changed, 98 insertions, 24 deletions
diff --git a/platforms/astbmc/astbmc.h b/platforms/astbmc/astbmc.h
index fb6c68a2..fc53d1a1 100644
--- a/platforms/astbmc/astbmc.h
+++ b/platforms/astbmc/astbmc.h
@@ -89,6 +89,7 @@ extern void astbmc_init(void);
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 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 6c90b7db..4b5d9a68 100644
--- a/platforms/astbmc/common.c
+++ b/platforms/astbmc/common.c
@@ -372,25 +372,13 @@ static void astbmc_fixup_psi_bar(void)
xscom_write(chip->id, 0x201090A, psibar);
}
-void astbmc_early_init(void)
+static void astbmc_fixup_uart(void)
{
- /* Hostboot's device-tree isn't quite right yet */
- astbmc_fixup_dt();
-
- /* Hostboot forgets to populate the PSI BAR */
- astbmc_fixup_psi_bar();
-
- /* Send external interrupts to me */
- psi_set_external_irq_policy(EXTERNAL_IRQ_POLICY_SKIBOOT);
-
- /* Initialize AHB accesses via AST2400 */
- ast_io_init();
-
/*
- * Depending on which image we are running, it may be configuring
- * the virtual UART or not. Check if VUART is enabled and use
- * SIO if not. We also correct the configuration of VUART as some
- * BMC images don't setup the interrupt properly
+ * Depending on which image we are running, it may be configuring the
+ * virtual UART or not. Check if VUART is enabled and use SIO if not.
+ * We also correct the configuration of VUART as some BMC images don't
+ * setup the interrupt properly
*/
if (ast_is_vuart1_enabled()) {
printf("PLAT: Using virtual UART\n");
@@ -400,11 +388,37 @@ void astbmc_early_init(void)
printf("PLAT: Using SuperIO UART\n");
ast_setup_sio_uart1(UART_IO_BASE, UART_LPC_IRQ);
}
+}
+
+void astbmc_early_init(void)
+{
+ /* Hostboot's device-tree isn't quite right yet */
+ astbmc_fixup_dt();
- /* Similarly, some BMCs don't configure the BT interrupt properly */
- ast_setup_ibt(BT_IO_BASE, BT_LPC_IRQ);
+ /* Hostboot forgets to populate the PSI BAR */
+ astbmc_fixup_psi_bar();
+
+ /* Send external interrupts to me */
+ psi_set_external_irq_policy(EXTERNAL_IRQ_POLICY_SKIBOOT);
- ast_setup_sio_mbox(MBOX_IO_BASE, MBOX_LPC_IRQ);
+ if (ast_sio_init()) {
+ if (!ast_can_isolate_sp()) {
+ /*
+ * BMCs claiming support for isolation must have
+ * correctly configured the UART and BT for host
+ * firmware. If not, let's apply some fixups for broken
+ * BMC firmwares.
+ */
+ if (ast_io_init()) {
+ astbmc_fixup_uart();
+ ast_setup_ibt(BT_IO_BASE, BT_LPC_IRQ);
+ } else
+ prerror("PLAT: AST IO initialisation failed!\n");
+ }
+
+ ast_setup_sio_mbox(MBOX_IO_BASE, MBOX_LPC_IRQ);
+ } else
+ prerror("PLAT: AST SIO initialisation failed!\n");
/* Setup UART and use it as console */
uart_init();
@@ -414,6 +428,64 @@ void astbmc_early_init(void)
prd_init();
}
+static bool astbmc_isolate_via_io(void)
+{
+ uint32_t hw_strapping;
+ uint32_t silicon_rev;
+ uint8_t family;
+
+ silicon_rev = ast_ahb_readl(SCU_REVISION_ID);
+ family = SCU_REVISION_SOC_FAMILY(silicon_rev);
+
+ if (family == SCU_REVISION_SOC_FAMILY_2400) {
+ /* Strapping is read-modify-write on SCU70 */
+ hw_strapping = SCU_STRAP_SIO_DECODE_DISABLE;
+ hw_strapping |= ast_ahb_readl(SCU_HW_STRAPPING);
+ } else if (family == SCU_REVISION_SOC_FAMILY_2500) {
+ /*
+ * Strapping is W1S on SCU70, W1C on SCU7C. We're setting a bit
+ * so read-modify-write *should* work, but in reality it breaks
+ * the AXI/AHB divider, so don't do that.
+ */
+ hw_strapping = SCU_STRAP_SIO_DECODE_DISABLE;
+ } else {
+ prerror("PLAT: Unrecognised BMC silicon revision 0x%x, isolation failed\n",
+ silicon_rev);
+ return false;
+ }
+
+ ast_ahb_writel(hw_strapping, SCU_HW_STRAPPING);
+
+ return true;
+}
+
+static bool astbmc_isolate_via_ipmi(void)
+{
+ return false;
+}
+
+static void astbmc_isolate(void)
+{
+ bool isolated;
+
+ isolated = ast_io_is_rw() ? astbmc_isolate_via_io()
+ : astbmc_isolate_via_ipmi();
+
+ if (!isolated) {
+ prlog(PR_EMERG, "PLAT: BMC isolation failed\n");
+ abort();
+ }
+
+ prlog(PR_INFO, "PLAT: Isolated BMC\n");
+}
+
+void astbmc_exit(void)
+{
+ if (ast_can_isolate_sp())
+ astbmc_isolate();
+ ipmi_wdt_final_reset();
+}
+
const struct bmc_platform astbmc_ami = {
.name = "AMI",
.ipmi_oem_partial_add_esel = IPMI_CODE(0x3a, 0xf0),
diff --git a/platforms/astbmc/romulus.c b/platforms/astbmc/romulus.c
index 8d3d1046..67c59463 100644
--- a/platforms/astbmc/romulus.c
+++ b/platforms/astbmc/romulus.c
@@ -80,6 +80,6 @@ DECLARE_PLATFORM(romulus) = {
.cec_power_down = astbmc_ipmi_power_down,
.cec_reboot = astbmc_ipmi_reboot,
.elog_commit = ipmi_elog_commit,
- .exit = ipmi_wdt_final_reset,
+ .exit = astbmc_exit,
.terminate = ipmi_terminate,
};
diff --git a/platforms/astbmc/witherspoon.c b/platforms/astbmc/witherspoon.c
index cb09eefe..d663709f 100644
--- a/platforms/astbmc/witherspoon.c
+++ b/platforms/astbmc/witherspoon.c
@@ -29,6 +29,7 @@
#include <phb4.h>
#include "astbmc.h"
+#include "ast.h"
/*
* HACK: Hostboot doesn't export the correct data for the system VPD EEPROM
@@ -165,7 +166,7 @@ DECLARE_PLATFORM(witherspoon) = {
.cec_power_down = astbmc_ipmi_power_down,
.cec_reboot = astbmc_ipmi_reboot,
.elog_commit = ipmi_elog_commit,
- .exit = ipmi_wdt_final_reset,
+ .exit = astbmc_exit,
.terminate = ipmi_terminate,
.pci_get_slot_info = dt_slot_get_slot_info,
diff --git a/platforms/qemu/qemu.c b/platforms/qemu/qemu.c
index dee61cce..a9b4f57b 100644
--- a/platforms/qemu/qemu.c
+++ b/platforms/qemu/qemu.c
@@ -246,8 +246,8 @@ static bool qemu_probe(void)
psi_set_external_irq_policy(EXTERNAL_IRQ_POLICY_SKIBOOT);
- /* Initialize AHB accesses via AST2400 */
- ast_io_init();
+ if (!ast_sio_init())
+ prerror("PLAT: AST SIO initialisation failed!\n");
/* Setup UART and use it as console */
uart_init();
OpenPOWER on IntegriCloud