On 2019-07-16 17:02:30 Tue, Hari Bathini wrote: > Introduce callback functions for platform specific operations like > register, unregister, invalidate & such. Also, define place-holders > for the same on pSeries platform. > > Signed-off-by: Hari Bathini <hbath...@linux.ibm.com> > --- > arch/powerpc/kernel/fadump-common.h | 33 ++++++ > arch/powerpc/kernel/fadump.c | 47 +-------- > arch/powerpc/platforms/pseries/Makefile | 1 > arch/powerpc/platforms/pseries/rtas-fadump.c | 134 > ++++++++++++++++++++++++++ > 4 files changed, 171 insertions(+), 44 deletions(-) > create mode 100644 arch/powerpc/platforms/pseries/rtas-fadump.c > > diff --git a/arch/powerpc/kernel/fadump-common.h > b/arch/powerpc/kernel/fadump-common.h > index 09d6161..020d582 100644 > --- a/arch/powerpc/kernel/fadump-common.h > +++ b/arch/powerpc/kernel/fadump-common.h > @@ -50,6 +50,12 @@ > #define FADUMP_UNREGISTER 2 > #define FADUMP_INVALIDATE 3 > > +/* Firmware-Assited Dump platforms */ > +enum fadump_platform_type { > + FADUMP_PLATFORM_UNKNOWN = 0, > + FADUMP_PLATFORM_PSERIES, > +};
Do we really need these ? Aren't we hiding all platform specific things under fadump_ops functions ? I see that these values are used only for assignements and not making any decision in code flow. Am I missing anything here ? Thanks, -Mahesh. > + > /* > * Copy the ascii values for first 8 characters from a string into u64 > * variable at their respective indexes. > @@ -84,6 +90,9 @@ struct fad_crash_memory_ranges { > unsigned long long size; > }; > > +/* Platform specific callback functions */ > +struct fadump_ops; > + > /* Firmware-assisted dump configuration details. */ > struct fw_dump { > unsigned long reserve_dump_area_start; > @@ -106,6 +115,21 @@ struct fw_dump { > unsigned long dump_active:1; > unsigned long dump_registered:1; > unsigned long nocma:1; > + > + enum fadump_platform_type fadump_platform; > + struct fadump_ops *ops; > +}; > + > +struct fadump_ops { > + ulong (*init_fadump_mem_struct)(struct fw_dump *fadump_config); > + int (*register_fadump)(struct fw_dump *fadump_config); > + int (*unregister_fadump)(struct fw_dump *fadump_config); > + int (*invalidate_fadump)(struct fw_dump *fadump_config); > + int (*process_fadump)(struct fw_dump *fadump_config); > + void (*fadump_region_show)(struct fw_dump *fadump_config, > + struct seq_file *m); > + void (*fadump_trigger)(struct fadump_crash_info_header *fdh, > + const char *msg); > }; > > /* Helper functions */ > @@ -116,4 +140,13 @@ void fadump_update_elfcore_header(struct fw_dump > *fadump_config, char *bufp); > int is_fadump_boot_mem_contiguous(struct fw_dump *fadump_conf); > int is_fadump_reserved_mem_contiguous(struct fw_dump *fadump_conf); > > +#ifdef CONFIG_PPC_PSERIES > +extern int rtas_fadump_dt_scan(struct fw_dump *fadump_config, ulong node); > +#else > +static inline int rtas_fadump_dt_scan(struct fw_dump *fadump_config, ulong > node) > +{ > + return 1; > +} > +#endif > + > #endif /* __PPC64_FA_DUMP_INTERNAL_H__ */ > diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c > index f571cb3..a901ca1 100644 > --- a/arch/powerpc/kernel/fadump.c > +++ b/arch/powerpc/kernel/fadump.c > @@ -112,24 +112,12 @@ static int __init fadump_cma_init(void) { return 1; } > int __init early_init_dt_scan_fw_dump(unsigned long node, const char *uname, > int depth, void *data) > { > - const __be32 *sections; > - int i, num_sections; > - int size; > - const __be32 *token; > + int ret; > > if (depth != 1 || strcmp(uname, "rtas") != 0) > return 0; > > - /* > - * Check if Firmware Assisted dump is supported. if yes, check > - * if dump has been initiated on last reboot. > - */ > - token = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL); > - if (!token) > - return 1; > - > - fw_dump.fadump_supported = 1; > - fw_dump.ibm_configure_kernel_dump = be32_to_cpu(*token); > + ret = rtas_fadump_dt_scan(&fw_dump, node); > > /* > * The 'ibm,kernel-dump' rtas node is present only if there is > @@ -139,36 +127,7 @@ int __init early_init_dt_scan_fw_dump(unsigned long > node, const char *uname, > if (fdm_active) > fw_dump.dump_active = 1; > > - /* Get the sizes required to store dump data for the firmware provided > - * dump sections. > - * For each dump section type supported, a 32bit cell which defines > - * the ID of a supported section followed by two 32 bit cells which > - * gives teh size of the section in bytes. > - */ > - sections = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump-sizes", > - &size); > - > - if (!sections) > - return 1; > - > - num_sections = size / (3 * sizeof(u32)); > - > - for (i = 0; i < num_sections; i++, sections += 3) { > - u32 type = (u32)of_read_number(sections, 1); > - > - switch (type) { > - case RTAS_FADUMP_CPU_STATE_DATA: > - fw_dump.cpu_state_data_size = > - of_read_ulong(§ions[1], 2); > - break; > - case RTAS_FADUMP_HPTE_REGION: > - fw_dump.hpte_region_size = > - of_read_ulong(§ions[1], 2); > - break; > - } > - } > - > - return 1; > + return ret; > } > > /* > diff --git a/arch/powerpc/platforms/pseries/Makefile > b/arch/powerpc/platforms/pseries/Makefile > index ab3d59a..e248724 100644 > --- a/arch/powerpc/platforms/pseries/Makefile > +++ b/arch/powerpc/platforms/pseries/Makefile > @@ -26,6 +26,7 @@ obj-$(CONFIG_IBMVIO) += vio.o > obj-$(CONFIG_IBMEBUS) += ibmebus.o > obj-$(CONFIG_PAPR_SCM) += papr_scm.o > obj-$(CONFIG_PPC_SPLPAR) += vphn.o > +obj-$(CONFIG_FA_DUMP) += rtas-fadump.o > > ifdef CONFIG_PPC_PSERIES > obj-$(CONFIG_SUSPEND) += suspend.o > diff --git a/arch/powerpc/platforms/pseries/rtas-fadump.c > b/arch/powerpc/platforms/pseries/rtas-fadump.c > new file mode 100644 > index 0000000..9e7c9bf > --- /dev/null > +++ b/arch/powerpc/platforms/pseries/rtas-fadump.c > @@ -0,0 +1,134 @@ > +/* > + * Firmware-Assisted Dump support on POWERVM platform. > + * > + * Copyright 2011, IBM Corporation > + * Author: Mahesh Salgaonkar <mah...@linux.ibm.com> > + * > + * Copyright 2019, IBM Corp. > + * Author: Hari Bathini <hbath...@linux.ibm.com> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version > + * 2 of the License, or (at your option) any later version. > + */ > + > +#undef DEBUG > +#define pr_fmt(fmt) "rtas fadump: " fmt > + > +#include <linux/string.h> > +#include <linux/memblock.h> > +#include <linux/delay.h> > +#include <linux/seq_file.h> > +#include <linux/crash_dump.h> > + > +#include <asm/page.h> > +#include <asm/prom.h> > +#include <asm/rtas.h> > +#include <asm/fadump.h> > + > +#include "../../kernel/fadump-common.h" > +#include "rtas-fadump.h" > + > +static ulong rtas_fadump_init_mem_struct(struct fw_dump *fadump_conf) > +{ > + return fadump_conf->reserve_dump_area_start; > +} > + > +static int rtas_fadump_register_fadump(struct fw_dump *fadump_conf) > +{ > + return -EIO; > +} > + > +static int rtas_fadump_unregister_fadump(struct fw_dump *fadump_conf) > +{ > + return -EIO; > +} > + > +static int rtas_fadump_invalidate_fadump(struct fw_dump *fadump_conf) > +{ > + return -EIO; > +} > + > +/* > + * Validate and process the dump data stored by firmware before exporting > + * it through '/proc/vmcore'. > + */ > +static int __init rtas_fadump_process_fadump(struct fw_dump *fadump_conf) > +{ > + return -EINVAL; > +} > + > +static void rtas_fadump_region_show(struct fw_dump *fadump_conf, > + struct seq_file *m) > +{ > +} > + > +static void rtas_fadump_trigger(struct fadump_crash_info_header *fdh, > + const char *msg) > +{ > + /* Call ibm,os-term rtas call to trigger firmware assisted dump */ > + rtas_os_term((char *)msg); > +} > + > +static struct fadump_ops rtas_fadump_ops = { > + .init_fadump_mem_struct = rtas_fadump_init_mem_struct, > + .register_fadump = rtas_fadump_register_fadump, > + .unregister_fadump = rtas_fadump_unregister_fadump, > + .invalidate_fadump = rtas_fadump_invalidate_fadump, > + .process_fadump = rtas_fadump_process_fadump, > + .fadump_region_show = rtas_fadump_region_show, > + .fadump_trigger = rtas_fadump_trigger, > +}; > + > +int __init rtas_fadump_dt_scan(struct fw_dump *fadump_conf, ulong node) > +{ > + const __be32 *sections; > + int i, num_sections; > + int size; > + const __be32 *token; > + > + /* > + * Check if Firmware Assisted dump is supported. if yes, check > + * if dump has been initiated on last reboot. > + */ > + token = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL); > + if (!token) > + return 1; > + > + fadump_conf->ibm_configure_kernel_dump = be32_to_cpu(*token); > + fadump_conf->ops = &rtas_fadump_ops; > + fadump_conf->fadump_platform = FADUMP_PLATFORM_PSERIES; > + fadump_conf->fadump_supported = 1; > + > + /* Get the sizes required to store dump data for the firmware provided > + * dump sections. > + * For each dump section type supported, a 32bit cell which defines > + * the ID of a supported section followed by two 32 bit cells which > + * gives the size of the section in bytes. > + */ > + sections = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump-sizes", > + &size); > + > + if (!sections) > + return 1; > + > + num_sections = size / (3 * sizeof(u32)); > + > + for (i = 0; i < num_sections; i++, sections += 3) { > + u32 type = (u32)of_read_number(sections, 1); > + > + switch (type) { > + case RTAS_FADUMP_CPU_STATE_DATA: > + fadump_conf->cpu_state_data_size = > + of_read_ulong(§ions[1], 2); > + break; > + case RTAS_FADUMP_HPTE_REGION: > + fadump_conf->hpte_region_size = > + of_read_ulong(§ions[1], 2); > + break; > + } > + } > + > + return 1; > +} > -- Mahesh J Salgaonkar