[RFC,11/16] hdata: Add result table property to ibm, dump node

Message ID 20180403120447.24364-12-hegdevasant@linux.vnet.ibm.com
State New
Headers show
Series
  • MPIPL support
Related show

Commit Message

Vasant Hegde April 3, 2018, 12:04 p.m.
result-table : Use fadump structure format to send MDRT table to host.

Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
---
 hdata/spira.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 hdata/spira.h |  3 +++
 2 files changed, 83 insertions(+), 1 deletion(-)

Patch

diff --git a/hdata/spira.c b/hdata/spira.c
index 5394e609f..1ceb0071b 100644
--- a/hdata/spira.c
+++ b/hdata/spira.c
@@ -26,6 +26,8 @@ 
 #include <fsp-attn.h>
 #include <fsp-leds.h>
 #include <skiboot.h>
+#include <mem_region-malloc.h>
+#include <opal-dump.h>
 
 #include "hdata.h"
 #include "hostservices.h"
@@ -1117,7 +1119,82 @@  static void add_iplparams_sys_params(const void *iplp, struct dt_node *node)
 		dt_init_secureboot_node(p);
 }
 
-static void add_fadump_node(const struct iplparams_iplparams *p __unused)
+static void add_fadump_result_table(struct dt_node *node,
+				    const struct iplparams_iplparams *p)
+{
+	int i, j = 0;
+	u32 mdrt_cnt = spira.ntuples.mdump_res.act_cnt;
+	size_t prop_size;
+	struct mdrt_table *mdrt = (void *)(MDRT_TABLE_BASE);
+	struct fadump_section *fadump_section;
+	struct fadump *result_table;
+
+	if (p->cec_ipl_maj_type != IPLPARAMS_MAJ_TYPE_REIPL ||
+	    p->cec_ipl_min_type != IPLPARAMS_MIN_TYPE_POST_DUMP)
+		return;
+	if (p->cec_ipl_attrib != IPLPARAMS_ATTRIB_MEM_PRESERVE)
+		return;
+
+	if (mdrt_cnt == 0)
+		return;
+
+	prlog(PR_DEBUG, "FADUMP: Dump found, MDRT count = 0x%x\n", mdrt_cnt);
+
+	/* Number of entries in MDRT table */
+	prop_size = sizeof(struct fadump) +
+		(mdrt_cnt * sizeof(struct fadump_section));
+	result_table = zalloc(prop_size);
+	if (!result_table) {
+		prlog(PR_ERR, "FADUMP: Failed to allocate memory\n");
+		return;
+	}
+
+	/* Copy MDRT entries to result-table */
+	result_table->fadump_section_size = sizeof(struct fadump_section);
+	for (i = 0; i < mdrt_cnt; i++) {
+		/* Skip garbage entry */
+		if ((mdrt->dest_addr == 0) || (mdrt->size == 0)) {
+			mdrt++;
+			continue;
+		}
+
+		/* Old hostboot? */
+		if (mdrt->data_region == 0) {
+			mdrt++;
+			continue;
+		}
+
+		if (mdrt->dump_type != DUMP_TYPE_FADUMP) {
+			mdrt++;
+			continue;
+		}
+
+		fadump_section = &(result_table->section[j++]);
+		fadump_section->source_type = mdrt->data_region;
+		/* Clear top bit */
+		fadump_section->source_addr = mdrt->src_addr & ~(HRMOR_BIT);
+		fadump_section->dest_addr = mdrt->dest_addr & ~(HRMOR_BIT);
+		fadump_section->source_size = mdrt->size;
+		fadump_section->dest_size = mdrt->size;
+		mdrt++;
+	}
+
+	if (j == 0) {
+		prlog(PR_DEBUG, "DUMP: MDRT table is empty\n");
+		free(result_table);
+		return;
+	}
+
+	/* TODO: Fill Architected register data */
+
+	result_table->section_count = j;
+	/* Actual property size */
+	prop_size = sizeof(struct fadump) + (j * sizeof(struct fadump_section));
+	dt_add_property(node, "result-table", result_table, prop_size);
+	free(result_table);
+}
+
+static void add_fadump_node(const struct iplparams_iplparams *p)
 {
 	u64 fw_load_area[4];
 	struct dt_node *node;
@@ -1134,6 +1211,8 @@  static void add_fadump_node(const struct iplparams_iplparams *p __unused)
 	fw_load_area[2] = (u64)INITRAMFS_LOAD_BASE;
 	fw_load_area[3] = INITRAMFS_LOAD_SIZE;
 	dt_add_property(node, "fw-load-area", fw_load_area, sizeof(fw_load_area));
+
+	add_fadump_result_table(node, p);
 }
 
 static void add_iplparams_ipl_params(const void *iplp, struct dt_node *node)
diff --git a/hdata/spira.h b/hdata/spira.h
index ef2aec257..c0be8212c 100644
--- a/hdata/spira.h
+++ b/hdata/spira.h
@@ -399,8 +399,11 @@  struct iplparams_iplparams {
 #define IPLPARAMS_FSP_FW_IPL_SIDE_TEMP	0x01
 	uint8_t		ipl_speed;
 	__be16		cec_ipl_attrib;
+#define IPLPARAMS_ATTRIB_MEM_PRESERVE	PPC_BIT16(2)
 	uint8_t		cec_ipl_maj_type;
+#define IPLPARAMS_MAJ_TYPE_REIPL	0x01
 	uint8_t		cec_ipl_min_type;
+#define IPLPARAMS_MIN_TYPE_POST_DUMP	0x0d
 	uint8_t		os_ipl_mode;
 	uint8_t		keylock_pos;
 	uint8_t		lmb_size;