[v9,10/25] MPIPL: Register for OPAL dump
diff mbox series

Message ID 20190712111802.23560-11-hegdevasant@linux.vnet.ibm.com
State Accepted
Headers show
Series
  • MPIPL support
Related show

Checks

Context Check Description
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot-dco success Signed-off-by present
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot success Test snowpatch/job/snowpatch-skiboot on branch master
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (4db38a36b31045f0a116d388ddeac850b38c8680)

Commit Message

Vasant Hegde July 12, 2019, 11:17 a.m. UTC
This patch adds support to register for OPAL dump.
  - Calculate memory required to capture OPAL dump
  - Reserve OPAL dump destination memory
  - Add OPAL dump details to MDST and MDDT table

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

Patch
diff mbox series

diff --git a/core/Makefile.inc b/core/Makefile.inc
index 64aa43ca2..3928f3219 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 d0f28f26d..fb55d4a9d 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.
@@ -53,6 +53,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;
@@ -1258,6 +1259,9 @@  void __noreturn __nomcount main_cpu_entry(const void *fdt)
 	/* Create the LPC bus interrupt-map on P9 */
 	lpc_finalize_interrupts();
 
+	/* init opal dump */
+	opal_mpipl_init();
+
 	/* Add the list of interrupts going to OPAL */
 	add_opal_interrupts();
 
diff --git a/core/opal-dump.c b/core/opal-dump.c
new file mode 100644
index 000000000..3d61f5092
--- /dev/null
+++ b/core/opal-dump.c
@@ -0,0 +1,144 @@ 
+/* 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;
+
+static int opal_mpipl_add_entry(u8 region, u64 src, u64 dest, u64 size)
+{
+	int i, max_cnt;
+	struct mdst_table *mdst;
+	struct mddt_table *mddt;
+
+	max_cnt = MDST_TABLE_SIZE / sizeof(struct mdst_table);
+	if (ntuple_mdst->act_cnt >= max_cnt) {
+		prlog(PR_DEBUG, "MDST table is full\n");
+		return OPAL_RESOURCE;
+	}
+
+	max_cnt = MDDT_TABLE_SIZE / sizeof(struct mddt_table);
+	if (ntuple_mdst->act_cnt >= max_cnt) {
+		prlog(PR_DEBUG, "MDDT table is full\n");
+		return OPAL_RESOURCE;
+	}
+
+	/* Use relocated memory address */
+	mdst = (void *)(MDST_TABLE_BASE);
+	mddt = (void *)(MDDT_TABLE_BASE);
+
+	/* Check for duplicate entry */
+	for (i = 0; i < ntuple_mdst->act_cnt; i++) {
+		if (mdst->addr == (src | HRMOR_BIT)) {
+			prlog(PR_DEBUG,
+			      "Duplicate source address : 0x%llx", src);
+			return OPAL_PARAMETER;
+		}
+		mdst++;
+	}
+	for (i = 0; i < ntuple_mddt->act_cnt; i++) {
+		if (mddt->addr == (dest | HRMOR_BIT)) {
+			prlog(PR_DEBUG,
+			      "Duplicate destination address : 0x%llx", dest);
+			return OPAL_PARAMETER;
+		}
+		mddt++;
+	}
+
+	/* Add OPAL source address to MDST entry */
+	mdst->addr = src | HRMOR_BIT;
+	mdst->data_region = region;
+	mdst->size = size;
+	ntuple_mdst->act_cnt++;
+
+	/* Add OPAL destination address to MDDT entry */
+	mddt->addr = dest | HRMOR_BIT;
+	mddt->data_region = region;
+	mddt->size = size;
+	ntuple_mddt->act_cnt++;
+
+	prlog(PR_TRACE, "Added new entry. src : 0x%llx, dest : 0x%llx,"
+	      " size : 0x%llx\n", src, dest, size);
+	return OPAL_SUCCESS;
+}
+
+/* Register for OPAL dump.  */
+static void opal_mpipl_register(void)
+{
+	u64 opal_dest, opal_size;
+
+	/* Get OPAL runtime size */
+	if (!dt_find_property(opal_node, "opal-runtime-size")) {
+		prlog(PR_DEBUG, "Could not get OPAL runtime size\n");
+		return;
+	}
+	opal_size = dt_prop_get_u64(opal_node, "opal-runtime-size");
+	if (!opal_size) {
+		prlog(PR_DEBUG, "OPAL runtime size is zero\n");
+		return;
+	}
+
+	/* Calculate and reserve OPAL dump destination memory */
+	opal_dest = SKIBOOT_BASE + opal_size;
+	mem_reserve_fw("ibm,firmware-dump", opal_dest, opal_size);
+
+	/* Add OPAL reservation detail to MDST/MDDT table */
+	opal_mpipl_add_entry(DUMP_REGION_OPAL_MEMORY,
+			     SKIBOOT_BASE, opal_dest, opal_size);
+}
+
+void opal_mpipl_init(void)
+{
+	void *mdst_base = (void *)MDST_TABLE_BASE;
+	void *mddt_base = (void *)MDDT_TABLE_BASE;
+	struct dt_node *dump_node;
+
+	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);
+
+	/* Clear MDST and MDDT table */
+	memset(mdst_base, 0, MDST_TABLE_SIZE);
+	ntuple_mdst->act_cnt = 0;
+	memset(mddt_base, 0, MDDT_TABLE_SIZE);
+	ntuple_mddt->act_cnt = 0;
+
+	opal_mpipl_register();
+}
diff --git a/include/opal-dump.h b/include/opal-dump.h
index ccf49f953..0a86dcb1b 100644
--- a/include/opal-dump.h
+++ b/include/opal-dump.h
@@ -33,6 +33,7 @@ 
 
 #define DUMP_REGION_CONSOLE	0x01
 #define DUMP_REGION_HBRT_LOG	0x02
+#define DUMP_REGION_OPAL_MEMORY	0x03
 
 /* Mainstore memory to be captured by FSP SYSDUMP */
 #define DUMP_TYPE_SYSDUMP		0xF5
@@ -120,4 +121,7 @@  struct proc_reg_data {
 	uint64_t reg_val;
 } __packed;
 
+/* init opal dump */
+extern void opal_mpipl_init(void);
+
 #endif	/* __OPAL_DUMP_H */