[Skiboot] [PATCH v9 20/25] MPIPL: Prepare OPAL data tag

Vasant Hegde hegdevasant at linux.vnet.ibm.com
Fri Jul 12 21:17:57 AEST 2019


Post MPIPL kernel needs OPAL metadata to create opalcore. This patch
sets up OPAL metadata tag. Next patch will add API to pass metadata
pointer to kernel.

Signed-off-by: Vasant Hegde <hegdevasant at linux.vnet.ibm.com>
---
 core/opal-dump.c   | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/opal-api.h | 20 ++++++++++++++++++
 2 files changed, 81 insertions(+)

diff --git a/core/opal-dump.c b/core/opal-dump.c
index bb90c45d0..15f82146c 100644
--- a/core/opal-dump.c
+++ b/core/opal-dump.c
@@ -41,6 +41,10 @@ static struct spira_ntuple *ntuple_mdrt;
 
 static struct mpipl_metadata    *mpipl_metadata;
 
+/* Dump metadata area */
+static struct opal_mpipl_fadump *opal_mpipl_data;
+
+
 static int opal_mpipl_add_entry(u8 region, u64 src, u64 dest, u64 size)
 {
 	int i, max_cnt;
@@ -329,6 +333,60 @@ static int64_t opal_mpipl_register_tag(enum opal_mpipl_tags tag,
 	return rc;
 }
 
+static void post_mpipl_get_opal_data(void)
+{
+	struct mdrt_table *mdrt = (void *)(MDRT_TABLE_BASE);
+	int i, j = 0, count = 0;
+	u32 mdrt_cnt = ntuple_mdrt->act_cnt;
+	struct opal_mpipl_region *region;
+
+	/* Count OPAL dump regions */
+	for (i = 0; i < mdrt_cnt; i++) {
+		if (mdrt->data_region == DUMP_REGION_OPAL_MEMORY)
+			count++;
+		mdrt++;
+	}
+
+	if (count == 0) {
+		prlog(PR_INFO, "OPAL dump is not available\n");
+		return;
+	}
+
+	opal_mpipl_data = zalloc(sizeof(struct opal_mpipl_fadump) +
+				 count * sizeof(struct opal_mpipl_region));
+	if (!opal_mpipl_data) {
+		prlog(PR_ERR, "Failed to allocate memory\n");
+		return;
+	}
+
+	/* Fill OPAL dump details */
+	opal_mpipl_data->version = OPAL_MPIPL_VERSION;
+	opal_mpipl_data->crashing_pir = mpipl_metadata->crashing_pir;
+	opal_mpipl_data->region_cnt = count;
+	region = opal_mpipl_data->region;
+
+	mdrt = (void *)(MDRT_TABLE_BASE);
+	for (i = 0; i < mdrt_cnt; i++) {
+		if (mdrt->data_region != DUMP_REGION_OPAL_MEMORY) {
+			mdrt++;
+			continue;
+		}
+
+		region[j].src  = mdrt->src_addr  & ~(HRMOR_BIT);
+		region[j].dest = mdrt->dest_addr & ~(HRMOR_BIT);
+		region[j].size = mdrt->size;
+
+		prlog(PR_NOTICE, "OPAL reserved region %d - src : 0x%llx, "
+		      "dest : 0x%llx, size : 0x%llx\n", j, region[j].src,
+		      region[j].dest, region[j].size);
+
+		mdrt++;
+		j++;
+		if (j == count)
+			break;
+	}
+}
+
 void opal_mpipl_save_crashing_pir(void)
 {
 	mpipl_metadata->crashing_pir = this_cpu()->pir;
@@ -353,6 +411,9 @@ void opal_mpipl_init(void)
 	/* Get metadata area pointer */
 	mpipl_metadata = (void *)(DUMP_METADATA_AREA_BASE);
 
+	if (dt_find_property(dump_node, "mpipl-boot"))
+		post_mpipl_get_opal_data();
+
 	/* Clear OPAL metadata area */
 	if (sizeof(struct mpipl_metadata) > DUMP_METADATA_AREA_SIZE) {
 		prlog(PR_ERR, "INSUFFICIENT OPAL METADATA AREA\n");
diff --git a/include/opal-api.h b/include/opal-api.h
index 939b836ca..25f4872e7 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -1236,6 +1236,26 @@ enum opal_mpipl_tags {
 	OPAL_MPIPL_TAG_BOOT_MEM	= 3,
 };
 
+/* Preserved memory details */
+struct opal_mpipl_region {
+	u64	src;
+	u64	dest;
+	u64	size;
+};
+
+/* Structure version */
+#define OPAL_MPIPL_VERSION		0x01
+
+struct opal_mpipl_fadump {
+	u8	version;
+	u8	reserved[7];
+	u32	crashing_pir;	/* OPAL crashing CPU PIR */
+	u32	cpu_data_version;
+	u32	cpu_data_size;
+	u32	region_cnt;
+	struct	opal_mpipl_region region[];
+} __packed;
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_API_H */
-- 
2.14.3



More information about the Skiboot mailing list