[Skiboot] [PATCH v2 10/12] opal: Enable backup topology.
Mahesh J Salgaonkar
mahesh at linux.vnet.ibm.com
Sat Jun 6 04:10:15 AEST 2015
From: Mahesh Salgaonkar <mahesh at linux.vnet.ibm.com>
Whenever FSP makes any changes to backup topology as part of either
routine hardware maintenance or fixing failed backup topology configuration,
it sends out mailbox command xE6, s/c 0x06, mod 0, to enable/disable
the backup topology. OPAL layer should keep itself up-to-date with accurate
details of current topology configurations. This will help OPAL layer to
successfully handle any TOD failover in future.
The FSP can only request that the currently inactive (backup) topology be
disabled or enabled. If the requested topology is currently the active
topology, then fail this request with a 0xB8 (TOD topology in use) status
as return code.
For disable request, set the backup topology status as disabled.
For enable request, scan all the available chips and find the new backup
master chip by looking at TOD status register of each chip.
Signed-off-by: Mahesh Salgaonkar <mahesh at linux.vnet.ibm.com>
---
Changes in V2:
- Moved fsp specific code under hw/fsp/fsp-chiptod.c
hw/chiptod.c | 70 ++++++++++++++++++++++++++++++++++++++----
hw/fsp/Makefile.inc | 2 +
hw/fsp/fsp-chiptod.c | 74 ++++++++++++++++++++++++++++++++++++++++++++
include/chiptod.h | 7 ++++
include/fsp.h | 9 +++++
platforms/ibm-fsp/common.c | 3 ++
6 files changed, 158 insertions(+), 7 deletions(-)
create mode 100644 hw/fsp/fsp-chiptod.c
diff --git a/hw/chiptod.c b/hw/chiptod.c
index 8ccfed8..50fdeaa 100644
--- a/hw/chiptod.c
+++ b/hw/chiptod.c
@@ -120,12 +120,6 @@ static enum chiptod_type {
chiptod_p8
} chiptod_type;
-enum chiptod_topology {
- chiptod_topo_unknown = -1,
- chiptod_topo_primary = 0,
- chiptod_topo_secondary = 1,
-};
-
enum chiptod_chip_role {
chiptod_chip_role_UNKNOWN = -1,
chiptod_chip_role_MDMT = 0, /* Master Drawer Master TOD */
@@ -1492,6 +1486,70 @@ static bool chiptod_probe(void)
return true;
}
+static void chiptod_discover_new_backup(enum chiptod_topology topo)
+{
+ struct proc_chip *chip = NULL;
+
+ /* Scan through available chips to find new backup master chip */
+ for_each_chip(chip) {
+ if (_chiptod_get_chip_status(chip->id) == chiptod_backup_master)
+ break;
+ }
+
+ /* Found new backup master chip. Update the topology info */
+ if (chip) {
+ prlog(PR_DEBUG, "CHIPTOD: New backup master: CHIP [%d]\n",
+ chip->id);
+
+ if (topo == chiptod_topo_primary)
+ chiptod_primary = chip->id;
+ else
+ chiptod_secondary = chip->id;
+ chiptod_topology_info[topo].id = chip->id;
+ chiptod_update_topology(topo);
+
+ prlog(PR_DEBUG,
+ "CHIPTOD: Backup topology configuration changed.\n");
+ print_topology_info();
+ }
+}
+
+/*
+ * Enable/disable backup topology.
+ * If request is to enable topology, then discover new backup master
+ * chip and update the topology configuration info. If the request is
+ * to disable topology, then mark the current backup topology as disabled.
+ * Return error (-1) if the action is requested on currenlty active
+ * topology.
+ *
+ * Return values:
+ * 0 <= Success
+ * -1 <= Topology is active and in use.
+ */
+int chiptod_adjust_topology(enum chiptod_topology topo, bool enable)
+{
+ uint8_t rc = 0;
+ /*
+ * The FSP can only request that the currently inactive topology
+ * be disabled or enabled. If the requested topology is currently
+ * the active topology, then fail this request with a -1 (TOD
+ * topology in use) status as return code.
+ */
+ lock(&chiptod_lock);
+ if (topo == current_topology) {
+ rc = -1;
+ goto out;
+ }
+
+ if (enable)
+ chiptod_discover_new_backup(topo);
+ else
+ chiptod_topology_info[topo].status = chiptod_backup_disabled;
+out:
+ unlock(&chiptod_lock);
+ return rc;
+}
+
static void chiptod_init_topology_info(void)
{
/* Find and update current topology in use. */
diff --git a/hw/fsp/Makefile.inc b/hw/fsp/Makefile.inc
index d4654d5..2fe4f0d 100644
--- a/hw/fsp/Makefile.inc
+++ b/hw/fsp/Makefile.inc
@@ -4,7 +4,7 @@ FSP_OBJS = fsp.o fsp-console.o fsp-rtc.o fsp-nvram.o fsp-sysparam.o
FSP_OBJS += fsp-surveillance.o fsp-codeupdate.o fsp-sensor.o
FSP_OBJS += fsp-diag.o fsp-leds.o fsp-mem-err.o fsp-op-panel.o
FSP_OBJS += fsp-elog-read.o fsp-elog-write.o fsp-epow.o fsp-dpo.o
-FSP_OBJS += fsp-dump.o fsp-mdst-table.o
+FSP_OBJS += fsp-dump.o fsp-mdst-table.o fsp-chiptod.o
FSP_OBJS += fsp-attn.o
FSP = hw/fsp/built-in.o
$(FSP): $(FSP_OBJS:%=hw/fsp/%)
diff --git a/hw/fsp/fsp-chiptod.c b/hw/fsp/fsp-chiptod.c
new file mode 100644
index 0000000..69c59c6
--- /dev/null
+++ b/hw/fsp/fsp-chiptod.c
@@ -0,0 +1,74 @@
+/* Copyright 2013-2014 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <skiboot.h>
+#include <chiptod.h>
+#include <fsp.h>
+
+/* Response status for fsp command 0xE6, s/c 0x06 (Enable/Disable Topology) */
+#define FSP_STATUS_TOPO_IN_USE 0xb8 /* topology is in use */
+
+static bool fsp_chiptod_update_topology(uint32_t cmd_sub_mod,
+ struct fsp_msg *msg __unused)
+{
+ struct fsp_msg *resp;
+ enum chiptod_topology topo;
+ bool action;
+ uint8_t rc;
+
+ switch (cmd_sub_mod) {
+ case FSP_CMD_TOPO_ENABLE_DISABLE:
+ /*
+ * Action Values: 0x00 = Disable, 0x01 = Enable
+ * Topology Values: 0x00 = Primary, 0x01 = Secondary
+ */
+ action = !!msg->data.bytes[2];
+ topo = msg->data.bytes[3];
+ prlog(PR_DEBUG, "CHIPTOD: Topology update event\n");
+ prlog(PR_DEBUG, "CHIPTOD: Action = %s, Topology = %s\n",
+ action ? "Enable" : "Disable",
+ topo ? "Secondary" : "Primary");
+
+ if (chiptod_adjust_topology(topo, action) < 0)
+ rc = FSP_STATUS_TOPO_IN_USE;
+
+ resp = fsp_mkmsg(FSP_RSP_TOPO_ENABLE_DISABLE | rc, 0);
+ if (!resp) {
+ prerror("CHIPTOD: Response allocation failed\n");
+ return false;
+ }
+ if (fsp_queue_msg(resp, fsp_freemsg)) {
+ fsp_freemsg(resp);
+ prerror("CHIPTOD: Failed to queue response msg\n");
+ }
+ return true;
+ default:
+ prlog(PR_DEBUG,
+ "CHIPTOD: Unhandled sub cmd: %06x\n", cmd_sub_mod);
+ break;
+ }
+ return false;
+}
+
+static struct fsp_client fsp_chiptod_client = {
+ .message = fsp_chiptod_update_topology,
+};
+
+void fsp_chiptod_init(void)
+{
+ /* Register for Class E6 (HW maintanance) */
+ fsp_register_client(&fsp_chiptod_client, FSP_MCLASS_HW_MAINT);
+}
diff --git a/include/chiptod.h b/include/chiptod.h
index 43f1d3d..07e3115 100644
--- a/include/chiptod.h
+++ b/include/chiptod.h
@@ -21,9 +21,16 @@
* time base across the fabric.
*/
+enum chiptod_topology {
+ chiptod_topo_unknown = -1,
+ chiptod_topo_primary = 0,
+ chiptod_topo_secondary = 1,
+};
+
extern void chiptod_init(void);
extern bool chiptod_wakeup_resync(void);
extern int chiptod_recover_tb_errors(void);
extern void chiptod_reset_tb(void);
+extern int chiptod_adjust_topology(enum chiptod_topology topo, bool enable);
#endif /* __CHIPTOD_H */
diff --git a/include/fsp.h b/include/fsp.h
index 5689798..3df78a1 100644
--- a/include/fsp.h
+++ b/include/fsp.h
@@ -520,6 +520,12 @@
#define FSP_CMD_VSERIAL_OUT 0x0e10200 /* HV->FSP */
/*
+ * Class E6
+ */
+#define FSP_CMD_TOPO_ENABLE_DISABLE 0x0e60600 /* FSP->HV */
+#define FSP_RSP_TOPO_ENABLE_DISABLE 0x0e68600 /* HV->FSP */
+
+/*
* Class E8
*/
#define FSP_CMD_READ_SRC 0x1e84a40 /* HV->FSP */
@@ -812,4 +818,7 @@ extern void fsp_epow_init(void);
/* DPO */
extern void fsp_dpo_init(void);
+/* Chiptod */
+extern void fsp_chiptod_init(void);
+
#endif /* __FSP_H */
diff --git a/platforms/ibm-fsp/common.c b/platforms/ibm-fsp/common.c
index d993b95..12536bd 100644
--- a/platforms/ibm-fsp/common.c
+++ b/platforms/ibm-fsp/common.c
@@ -110,6 +110,9 @@ void ibm_fsp_init(void)
/* Initialize SP attention area */
fsp_attn_init();
+ /* Initialize monitoring of TOD topology change event notification */
+ fsp_chiptod_init();
+
/* Send MDST table notification to FSP */
op_display(OP_LOG, OP_MOD_INIT, 0x0000);
fsp_mdst_table_init();
More information about the Skiboot
mailing list