aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasant Hegde <hegdevasant@linux.vnet.ibm.com>2019-07-12 16:47:57 +0530
committerOliver O'Halloran <oohall@gmail.com>2019-08-15 17:54:11 +1000
commit3d85abd9d3e15885ef4c2be08d2e89d4d4247d6d (patch)
tree7494b841e828059278edc293dfd7cea791a97672
parent6326c712e770c398cb39dbc7346f13bbf1166cea (diff)
downloadskiboot-3d85abd9d3e15885ef4c2be08d2e89d4d4247d6d.zip
skiboot-3d85abd9d3e15885ef4c2be08d2e89d4d4247d6d.tar.gz
skiboot-3d85abd9d3e15885ef4c2be08d2e89d4d4247d6d.tar.bz2
MPIPL: Prepare OPAL data tag
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@linux.vnet.ibm.com> [oliver: rebased] Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
-rw-r--r--core/opal-dump.c61
-rw-r--r--include/opal-api.h20
2 files changed, 81 insertions, 0 deletions
diff --git a/core/opal-dump.c b/core/opal-dump.c
index bb90c45..15f8214 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 1a1f380..7d8e046 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -1223,6 +1223,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 */