[Skiboot] [PATCH v7 13/22] fadump: Add fw-source-table to ibm, opal/dump node

Vasant Hegde hegdevasant at linux.vnet.ibm.com
Sat Apr 13 19:15:39 AEST 2019


Add 'fw-source-table' property to ibm,opal/dump node. Payload will make
use of this property to create ELF notes.

This patch also adjusts MDST and MDDT entry for OPAL dump. Now OPAL dump
size reflects runtime size of OPAL.

Finally add reserve node for opal dump destination memory. If dump is available
then reserve node size is max of current dump destination size and memory
reserved for next dump.

Signed-off-by: Vasant Hegde <hegdevasant at linux.vnet.ibm.com>
---
 core/Makefile.inc   |   2 +-
 core/init.c         |   6 +-
 core/opal-dump.c    | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/opal-dump.h |   4 ++
 4 files changed, 184 insertions(+), 2 deletions(-)
 create mode 100644 core/opal-dump.c

diff --git a/core/Makefile.inc b/core/Makefile.inc
index 3b4387081..a1a5e5b40 100644
--- a/core/Makefile.inc
+++ b/core/Makefile.inc
@@ -10,7 +10,7 @@ CORE_OBJS += console-log.o ipmi.o time-utils.o pel.o pool.o errorlog.o
 CORE_OBJS += timer.o i2c.o rtc.o flash.o sensor.o ipmi-opal.o
 CORE_OBJS += flash-subpartition.o bitmap.o buddy.o pci-quirk.o powercap.o psr.o
 CORE_OBJS += pci-dt-slot.o direct-controls.o cpufeatures.o
-CORE_OBJS += flash-firmware-versions.o
+CORE_OBJS += flash-firmware-versions.o opal-dump.o
 
 ifeq ($(SKIBOOT_GCOV),1)
 CORE_OBJS += gcov-profiling.o
diff --git a/core/init.c b/core/init.c
index eeee2d9e9..64d763c70 100644
--- a/core/init.c
+++ b/core/init.c
@@ -1,4 +1,4 @@
-/* Copyright 2013-2016 IBM Corp.
+/* Copyright 2013-2019 IBM Corp.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -54,6 +54,7 @@
 #include <sbe-p9.h>
 #include <debug_descriptor.h>
 #include <occ.h>
+#include <opal-dump.h>
 
 enum proc_gen proc_gen;
 unsigned int pcie_max_link_speed;
@@ -1146,6 +1147,9 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)
 	 */
 	p9_sbe_init();
 
+	/* init opal dump */
+	opal_dump_init();
+
 	/* Initialize i2c */
 	p8_i2c_init();
 
diff --git a/core/opal-dump.c b/core/opal-dump.c
new file mode 100644
index 000000000..8e4014335
--- /dev/null
+++ b/core/opal-dump.c
@@ -0,0 +1,174 @@
+/* Copyright 2019 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.
+ */
+
+#define pr_fmt(fmt)	"DUMP: " fmt
+
+#include <device.h>
+#include <mem-map.h>
+#include <mem_region.h>
+#include <mem_region-malloc.h>
+#include <opal.h>
+#include <opal-dump.h>
+#include <opal-internal.h>
+#include <skiboot.h>
+
+#include <ccan/endian/endian.h>
+
+#include "hdata/spira.h"
+
+/* Actual address of MDST and MDDT table */
+#define MDST_TABLE_BASE		(SKIBOOT_BASE + MDST_TABLE_OFF)
+#define MDDT_TABLE_BASE		(SKIBOOT_BASE + MDDT_TABLE_OFF)
+
+static struct spira_ntuple *ntuple_mdst;
+static struct spira_ntuple *ntuple_mddt;
+static struct spira_ntuple *ntuple_mdrt;
+
+
+/* Reserve OPAL dump destination memory */
+static void add_dump_reserve_node(struct dt_node *dump_node)
+{
+	int i;
+	u64 cur_size = 0, new_size = 0;
+	/* Use relocated memory address */
+	struct mddt_table *mddt = (void *)(MDDT_TABLE_BASE);
+	struct mdrt_table *mdrt = (void *)(MDRT_TABLE_BASE);
+
+	/* If dump exists, get current opal dump size */
+	if (dt_find_property(dump_node, "result-table")) {
+		for (i = 0; i < ntuple_mdrt->act_cnt; i++) {
+			if (mdrt->data_region >= DUMP_REGION_OPAL_START &&
+			    mdrt->data_region < DUMP_REGION_OPAL_END)
+				cur_size += be32_to_cpu(mdrt->size);
+
+			mdrt++;
+		}
+	}
+
+	/* Get new OPAL dump reservation size */
+	for (i = 0; i < ntuple_mddt->act_cnt; i++) {
+		if (mddt->data_region >= DUMP_REGION_OPAL_START &&
+		    mddt->data_region < DUMP_REGION_OPAL_END)
+			new_size += be32_to_cpu(mddt->size);
+
+		mddt++;
+	}
+
+	mem_reserve_fw("ibm,firmware-dump", (u64)OPAL_DUMP_DEST_BASE,
+		       new_size > cur_size ? new_size : cur_size);
+}
+
+/* Pass OPAL dump reservation details to payload via device tree. */
+static void dt_add_dump_source_table(struct dt_node *dump_node,
+				     struct mdst_table *mdst,
+				     struct mddt_table *mddt)
+{
+	size_t prop_size;
+	struct fadump *source_table;
+
+	if (mdst->data_region != DUMP_REGION_OPAL_MEMORY ||
+	    mddt->data_region != DUMP_REGION_OPAL_MEMORY) {
+		prlog(PR_DEBUG,
+		      "OPAL memory entry is missing in MDST/MDDT table\n");
+		return;
+	}
+
+	prop_size = sizeof(struct fadump) + sizeof(struct fadump_section);
+	source_table = zalloc(prop_size);
+	if (!source_table) {
+		prlog(PR_ERR, "Failed to allocate memory\n");
+		return;
+	}
+
+	source_table->fadump_section_size = sizeof(struct fadump_section);
+	source_table->section_count = 1;
+	source_table->section[0].source_type = mdst->data_region;
+	source_table->section[0].source_addr =
+			cpu_to_be64(mdst->addr & ~(HRMOR_BIT));
+	source_table->section[0].source_size = cpu_to_be64(mdst->size);
+	source_table->section[0].dest_addr =
+			cpu_to_be64(mddt->addr & ~(HRMOR_BIT));
+	source_table->section[0].dest_size = cpu_to_be64(mddt->size);
+
+	dt_add_property(dump_node, "fw-source-table", source_table, prop_size);
+	free(source_table);
+}
+
+/*
+ * OPAL adjusts runtime OPAL size based on number of CPUs and PIR value.
+ * Hardcoded dump entry in MDST and MDDT table contains maximum size required
+ * to capture OPAL dump (so that we can capture early OPAL dump). Adjust
+ * OPAL dump entry in MDST and MDDT to reflect OPAL runtime size.
+ */
+static void adjust_opal_dump_size(struct dt_node *dump_node)
+{
+	int i;
+	u64 opal_size;
+	/* Use relocated memory address */
+	struct mdst_table *mdst = (void *)(MDST_TABLE_BASE);
+	struct mddt_table *mddt = (void *)(MDDT_TABLE_BASE);
+
+	/* Get OPAL runtime size */
+	if (!dt_find_property(opal_node, "opal-runtime-size"))
+		return;
+	opal_size = dt_prop_get_u64(opal_node, "opal-runtime-size");
+
+	/* Safe to assume MDST, MDDT table contains entry for OPAL dump
+	 * (see hdata/spira.c)
+	 */
+	for (i = 0; i < ntuple_mdst->act_cnt; i++) {
+		if (mdst->data_region != DUMP_REGION_OPAL_MEMORY) {
+			mdst++;
+			continue;
+		}
+		mdst->size = opal_size;
+		break;
+	}
+
+	for (i = 0; i < ntuple_mddt->act_cnt; i++) {
+		if (mddt->data_region != DUMP_REGION_OPAL_MEMORY) {
+			mddt++;
+			continue;
+		}
+		mddt->size = opal_size;
+		break;
+	}
+
+	/* Add OPAL dump reservation details to DT */
+	dt_add_dump_source_table(dump_node, mdst, mddt);
+	/* Make sure OPAL dump destination memory is reserved */
+	add_dump_reserve_node(dump_node);
+}
+
+void opal_dump_init(void)
+{
+	struct dt_node *dump_node;
+
+	if (proc_gen < proc_gen_p9)
+		return;
+
+	/* fadump needs HDAT support */
+	dump_node = dt_find_by_path(opal_node, "dump");
+	if (!dump_node)
+		return;
+
+	/* Get MDST and MDDT ntuple from SPIRAH */
+	ntuple_mdst = &(spirah.ntuples.mdump_src);
+	ntuple_mddt = &(spirah.ntuples.mdump_dst);
+	ntuple_mdrt = &(spirah.ntuples.mdump_res);
+
+	adjust_opal_dump_size(dump_node);
+}
diff --git a/include/opal-dump.h b/include/opal-dump.h
index 1f97be0cc..d71691e13 100644
--- a/include/opal-dump.h
+++ b/include/opal-dump.h
@@ -123,4 +123,8 @@ struct proc_reg_data {
 	uint64_t reg_val;
 } __packed;
 
+
+/* init opal dump */
+extern void opal_dump_init(void);
+
 #endif	/* __OPAL_DUMP_H */
-- 
2.14.3



More information about the Skiboot mailing list