summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/powernv/opal-fadump.c54
-rw-r--r--arch/powerpc/platforms/powernv/opal-fadump.h5
-rw-r--r--arch/powerpc/platforms/pseries/rtas-fadump.c11
-rw-r--r--arch/powerpc/platforms/pseries/rtas-fadump.h5
4 files changed, 45 insertions, 30 deletions
diff --git a/arch/powerpc/platforms/powernv/opal-fadump.c b/arch/powerpc/platforms/powernv/opal-fadump.c
index 006648e4d5e6..d361d37d975f 100644
--- a/arch/powerpc/platforms/powernv/opal-fadump.c
+++ b/arch/powerpc/platforms/powernv/opal-fadump.c
@@ -115,19 +115,28 @@ static void opal_fadump_update_config(struct fw_dump *fadump_conf,
static void opal_fadump_get_config(struct fw_dump *fadump_conf,
const struct opal_fadump_mem_struct *fdm)
{
+ unsigned long base, size, last_end, hole_size;
int i;
if (!fadump_conf->dump_active)
return;
+ last_end = 0;
+ hole_size = 0;
fadump_conf->boot_memory_size = 0;
pr_debug("Boot memory regions:\n");
for (i = 0; i < fdm->region_cnt; i++) {
- pr_debug("\t%d. base: 0x%llx, size: 0x%llx\n",
- (i + 1), fdm->rgn[i].src, fdm->rgn[i].size);
+ base = fdm->rgn[i].src;
+ size = fdm->rgn[i].size;
+ pr_debug("\t[%03d] base: 0x%lx, size: 0x%lx\n", i, base, size);
- fadump_conf->boot_memory_size += fdm->rgn[i].size;
+ fadump_conf->boot_mem_addr[i] = base;
+ fadump_conf->boot_mem_sz[i] = size;
+ fadump_conf->boot_memory_size += size;
+ hole_size += (base - last_end);
+
+ last_end = base + size;
}
/*
@@ -160,6 +169,8 @@ static void opal_fadump_get_config(struct fw_dump *fadump_conf,
pr_warn("WARNING: If the unsaved regions contain kernel pages, the vmcore will be corrupted.\n");
}
+ fadump_conf->boot_mem_top = (fadump_conf->boot_memory_size + hole_size);
+ fadump_conf->boot_mem_regs_cnt = fdm->region_cnt;
opal_fadump_update_config(fadump_conf, fdm);
}
@@ -174,33 +185,20 @@ static void opal_fadump_init_metadata(struct opal_fadump_mem_struct *fdm)
static u64 opal_fadump_init_mem_struct(struct fw_dump *fadump_conf)
{
- int max_copy_size, cur_size, size;
- u64 src_addr, dest_addr;
+ u64 addr = fadump_conf->reserve_dump_area_start;
+ int i;
opal_fdm = __va(fadump_conf->kernel_metadata);
opal_fadump_init_metadata(opal_fdm);
- /*
- * Firmware supports 32-bit field for size. Align it to PAGE_SIZE
- * and request firmware to copy multiple kernel boot memory regions.
- */
- max_copy_size = _ALIGN_DOWN(U32_MAX, PAGE_SIZE);
-
/* Boot memory regions */
- src_addr = 0;
- dest_addr = fadump_conf->reserve_dump_area_start;
- size = fadump_conf->boot_memory_size;
- while (size) {
- cur_size = size > max_copy_size ? max_copy_size : size;
-
- opal_fdm->rgn[opal_fdm->region_cnt].src = src_addr;
- opal_fdm->rgn[opal_fdm->region_cnt].dest = dest_addr;
- opal_fdm->rgn[opal_fdm->region_cnt].size = cur_size;
+ for (i = 0; i < fadump_conf->boot_mem_regs_cnt; i++) {
+ opal_fdm->rgn[i].src = fadump_conf->boot_mem_addr[i];
+ opal_fdm->rgn[i].dest = addr;
+ opal_fdm->rgn[i].size = fadump_conf->boot_mem_sz[i];
opal_fdm->region_cnt++;
- dest_addr += cur_size;
- src_addr += cur_size;
- size -= cur_size;
+ addr += fadump_conf->boot_mem_sz[i];
}
/*
@@ -212,7 +210,7 @@ static u64 opal_fadump_init_mem_struct(struct fw_dump *fadump_conf)
opal_fadump_update_config(fadump_conf, opal_fdm);
- return dest_addr;
+ return addr;
}
static u64 opal_fadump_get_metadata_size(void)
@@ -254,7 +252,7 @@ static int opal_fadump_setup_metadata(struct fw_dump *fadump_conf)
* by a kernel that intends to preserve crash'ed kernel's memory.
*/
ret = opal_mpipl_register_tag(OPAL_MPIPL_TAG_BOOT_MEM,
- fadump_conf->boot_memory_size);
+ fadump_conf->boot_mem_top);
if (ret != OPAL_SUCCESS) {
pr_err("Failed to set boot memory tag!\n");
err = -EPERM;
@@ -670,6 +668,12 @@ void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)
fadump_conf->fadump_supported = 1;
/*
+ * Firmware supports 32-bit field for size. Align it to PAGE_SIZE
+ * and request firmware to copy multiple kernel boot memory regions.
+ */
+ fadump_conf->max_copy_size = _ALIGN_DOWN(U32_MAX, PAGE_SIZE);
+
+ /*
* Check if dump has been initiated on last reboot.
*/
prop = of_get_flat_dt_prop(dn, "mpipl-boot", NULL);
diff --git a/arch/powerpc/platforms/powernv/opal-fadump.h b/arch/powerpc/platforms/powernv/opal-fadump.h
index e630cb0f108f..f1e9ecf548c5 100644
--- a/arch/powerpc/platforms/powernv/opal-fadump.h
+++ b/arch/powerpc/platforms/powernv/opal-fadump.h
@@ -27,9 +27,6 @@
*/
#define OPAL_FADUMP_VERSION 0x1
-/* Maximum number of memory regions kernel supports */
-#define OPAL_FADUMP_MAX_MEM_REGS 128
-
/*
* OPAL FADump kernel metadata
*
@@ -42,7 +39,7 @@ struct opal_fadump_mem_struct {
u16 region_cnt; /* number of regions */
u16 registered_regions; /* Regions registered for MPIPL */
u64 fadumphdr_addr;
- struct opal_mpipl_region rgn[OPAL_FADUMP_MAX_MEM_REGS];
+ struct opal_mpipl_region rgn[FADUMP_MAX_MEM_REGS];
} __packed;
/*
diff --git a/arch/powerpc/platforms/pseries/rtas-fadump.c b/arch/powerpc/platforms/pseries/rtas-fadump.c
index a525180c1f0f..70c3013fdd07 100644
--- a/arch/powerpc/platforms/pseries/rtas-fadump.c
+++ b/arch/powerpc/platforms/pseries/rtas-fadump.c
@@ -42,7 +42,13 @@ static void rtas_fadump_update_config(struct fw_dump *fadump_conf,
static void rtas_fadump_get_config(struct fw_dump *fadump_conf,
const struct rtas_fadump_mem_struct *fdm)
{
- fadump_conf->boot_memory_size = be64_to_cpu(fdm->rmr_region.source_len);
+ fadump_conf->boot_mem_addr[0] =
+ be64_to_cpu(fdm->rmr_region.source_address);
+ fadump_conf->boot_mem_sz[0] = be64_to_cpu(fdm->rmr_region.source_len);
+ fadump_conf->boot_memory_size = fadump_conf->boot_mem_sz[0];
+
+ fadump_conf->boot_mem_top = fadump_conf->boot_memory_size;
+ fadump_conf->boot_mem_regs_cnt = 1;
/*
* Start address of reserve dump area (permanent reservation) for
@@ -499,6 +505,9 @@ void __init rtas_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)
fadump_conf->ops = &rtas_fadump_ops;
fadump_conf->fadump_supported = 1;
+ /* Firmware supports 64-bit value for size, align it to pagesize. */
+ fadump_conf->max_copy_size = _ALIGN_DOWN(U64_MAX, PAGE_SIZE);
+
/*
* The 'ibm,kernel-dump' rtas node is present only if there is
* dump data waiting for us.
diff --git a/arch/powerpc/platforms/pseries/rtas-fadump.h b/arch/powerpc/platforms/pseries/rtas-fadump.h
index 6602ff69e10d..fd59bd7ca9c3 100644
--- a/arch/powerpc/platforms/pseries/rtas-fadump.h
+++ b/arch/powerpc/platforms/pseries/rtas-fadump.h
@@ -69,6 +69,11 @@ struct rtas_fadump_mem_struct {
/* Kernel dump sections */
struct rtas_fadump_section cpu_state_data;
struct rtas_fadump_section hpte_region;
+
+ /*
+ * TODO: Extend multiple boot memory regions support in the kernel
+ * for this platform.
+ */
struct rtas_fadump_section rmr_region;
};