[PATCH 2/4] powerpc/pseries: Move DRMEM processing out of prom.c
Michael Bringmann
mwb at linux.vnet.ibm.com
Wed Nov 28 07:35:21 AEDT 2018
The implementation of the pseries-specific dynamic memory features
is currently implemented in several non-pseries-specific files.
This patch set moves the implementation of the device-tree parsing
code for the properties ibm,dynamic-memory, ibm,dynamic-memory-v2,
and its representation in the kernel into the platform-specific
directory to the Pseries features.
This patch refactors references to drmem features out of prom.c, so
that they can be moved to drmem.c. Changes include creating a
platform function platform_early_init_dt_scan_memory_ppc that any
powerpc platform may implement, and moving a support function to
powerpc/include/asm/sparsemem.h
Signed-off-by: Michael Bringmann <mwb at linux.vnet.ibm.com>
---
arch/powerpc/include/asm/platform.h | 23 ++++++++
arch/powerpc/include/asm/prom.h | 3 +
arch/powerpc/include/asm/sparsemem.h | 19 +++++++
arch/powerpc/kernel/prom.c | 90 +-------------------------------
arch/powerpc/platforms/pseries/drmem.c | 73 ++++++++++++++++++++++++++
5 files changed, 122 insertions(+), 86 deletions(-)
create mode 100644 arch/powerpc/include/asm/platform.h
diff --git a/arch/powerpc/include/asm/platform.h b/arch/powerpc/include/asm/platform.h
new file mode 100644
index 0000000..36f0f9e
--- /dev/null
+++ b/arch/powerpc/include/asm/platform.h
@@ -0,0 +1,23 @@
+#ifndef _POWERPC_PLATFORM_H
+#define _POWERPC_PLATFORM_H
+#ifdef __KERNEL__
+
+/*
+ * Definitions for talking to the Platform-specific functions of PowerPC
+ *
+ * Copyright (C) 2018 Michael Bringmann, IBM Corp.
+ *
+ * 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.
+ */
+#include <linux/types.h>
+
+/* Memory initialization support */
+extern int platform_early_init_dt_scan_memory_ppc(unsigned long node,
+ const char *uname,
+ int depth, void *data);
+
+#endif /* __KERNEL__ */
+#endif /* _POWERPC_PLATFORM_H */
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index b04c5ce..4504773 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -180,5 +180,8 @@ extern int of_read_drc_info_cell(struct property **prop,
/* Option Vector 6: IBM PAPR hints */
#define OV6_LINUX 0x02 /* Linux is our OS */
+/* Other functions */
+extern bool validate_mem_limit(u64 base, u64 *size);
+
#endif /* __KERNEL__ */
#endif /* _POWERPC_PROM_H */
diff --git a/arch/powerpc/include/asm/sparsemem.h b/arch/powerpc/include/asm/sparsemem.h
index 68da493..25edfc2 100644
--- a/arch/powerpc/include/asm/sparsemem.h
+++ b/arch/powerpc/include/asm/sparsemem.h
@@ -32,5 +32,24 @@ static inline int hot_add_scn_to_nid(unsigned long scn_addr)
#endif /* CONFIG_NUMA */
#endif /* CONFIG_MEMORY_HOTPLUG */
+
+#ifdef CONFIG_SPARSEMEM
+static inline bool validate_mem_limit(u64 base, u64 *size)
+{
+ u64 max_mem = 1UL << (MAX_PHYSMEM_BITS);
+
+ if (base >= max_mem)
+ return false;
+ if ((base + *size) > max_mem)
+ *size = max_mem - base;
+ return true;
+}
+#else
+static inline bool validate_mem_limit(u64 base, u64 *size)
+{
+ return true;
+}
+#endif
+
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_SPARSEMEM_H */
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index fe758ce..ea32fee 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -58,7 +58,7 @@
#include <asm/epapr_hcalls.h>
#include <asm/firmware.h>
#include <asm/dt_cpu_ftrs.h>
-#include <asm/drmem.h>
+#include <asm/platform.h>
#include <mm/mmu_decl.h>
@@ -444,96 +444,14 @@ static int __init early_init_dt_scan_chosen_ppc(unsigned long node,
* size if it cross the limit.
*/
-#ifdef CONFIG_SPARSEMEM
-static bool validate_mem_limit(u64 base, u64 *size)
-{
- u64 max_mem = 1UL << (MAX_PHYSMEM_BITS);
-
- if (base >= max_mem)
- return false;
- if ((base + *size) > max_mem)
- *size = max_mem - base;
- return true;
-}
-#else
-static bool validate_mem_limit(u64 base, u64 *size)
-{
- return true;
-}
-#endif
-
-#ifdef CONFIG_PPC_PSERIES
-/*
- * Interpret the ibm dynamic reconfiguration memory LMBs.
- * This contains a list of memory blocks along with NUMA affinity
- * information.
- */
-static void __init early_init_drmem_lmb(struct drmem_lmb *lmb,
- const __be32 **usm)
-{
- u64 base, size;
- int is_kexec_kdump = 0, rngs;
-
- base = lmb->base_addr;
- size = drmem_lmb_size();
- rngs = 1;
-
- /*
- * Skip this block if the reserved bit is set in flags
- * or if the block is not assigned to this partition.
- */
- if ((lmb->flags & DRCONF_MEM_RESERVED) ||
- !(lmb->flags & DRCONF_MEM_ASSIGNED))
- return;
-
- if (*usm)
- is_kexec_kdump = 1;
-
- if (is_kexec_kdump) {
- /*
- * For each memblock in ibm,dynamic-memory, a
- * corresponding entry in linux,drconf-usable-memory
- * property contains a counter 'p' followed by 'p'
- * (base, size) duple. Now read the counter from
- * linux,drconf-usable-memory property
- */
- rngs = dt_mem_next_cell(dt_root_size_cells, usm);
- if (!rngs) /* there are no (base, size) duple */
- return;
- }
-
- do {
- if (is_kexec_kdump) {
- base = dt_mem_next_cell(dt_root_addr_cells, usm);
- size = dt_mem_next_cell(dt_root_size_cells, usm);
- }
-
- if (iommu_is_off) {
- if (base >= 0x80000000ul)
- continue;
- if ((base + size) > 0x80000000ul)
- size = 0x80000000ul - base;
- }
-
- DBG("Adding: %llx -> %llx\n", base, size);
- if (validate_mem_limit(base, &size))
- memblock_add(base, size);
- } while (--rngs);
-}
-#endif /* CONFIG_PPC_PSERIES */
-
static int __init early_init_dt_scan_memory_ppc(unsigned long node,
const char *uname,
int depth, void *data)
{
-#ifdef CONFIG_PPC_PSERIES
- if (depth == 1 &&
- strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) {
- walk_drmem_lmbs_early(node, early_init_drmem_lmb);
+ if (!platform_early_init_dt_scan_memory_ppc(node, uname,
+ depth, data))
return 0;
- }
-#endif
-
+
return early_init_dt_scan_memory(node, uname, depth, data);
}
diff --git a/arch/powerpc/platforms/pseries/drmem.c b/arch/powerpc/platforms/pseries/drmem.c
index 3f18036..ccb0d3b 100644
--- a/arch/powerpc/platforms/pseries/drmem.c
+++ b/arch/powerpc/platforms/pseries/drmem.c
@@ -17,6 +17,7 @@
#include <linux/memblock.h>
#include <asm/prom.h>
#include <asm/drmem.h>
+#include <asm/platform.h>
static struct drmem_lmb_info __drmem_info;
struct drmem_lmb_info *drmem_info = &__drmem_info;
@@ -445,3 +446,75 @@ static int __init drmem_init(void)
return 0;
}
late_initcall(drmem_init);
+
+
+/*
+ * Interpret the ibm dynamic reconfiguration memory LMBs.
+ * This contains a list of memory blocks along with NUMA affinity
+ * information.
+ */
+static void __init early_init_drmem_lmb(struct drmem_lmb *lmb,
+ const __be32 **usm)
+{
+ u64 base, size;
+ int is_kexec_kdump = 0, rngs;
+
+ base = lmb->base_addr;
+ size = drmem_lmb_size();
+ rngs = 1;
+
+ /*
+ * Skip this block if the reserved bit is set in flags
+ * or if the block is not assigned to this partition.
+ */
+ if ((lmb->flags & DRCONF_MEM_RESERVED) ||
+ !(lmb->flags & DRCONF_MEM_ASSIGNED))
+ return;
+
+ if (*usm)
+ is_kexec_kdump = 1;
+
+ if (is_kexec_kdump) {
+ /*
+ * For each memblock in ibm,dynamic-memory, a
+ * corresponding entry in linux,drconf-usable-memory
+ * property contains a counter 'p' followed by 'p'
+ * (base, size) duple. Now read the counter from
+ * linux,drconf-usable-memory property
+ */
+ rngs = dt_mem_next_cell(dt_root_size_cells, usm);
+ if (!rngs) /* there are no (base, size) duple */
+ return;
+ }
+
+ do {
+ if (is_kexec_kdump) {
+ base = dt_mem_next_cell(dt_root_addr_cells, usm);
+ size = dt_mem_next_cell(dt_root_size_cells, usm);
+ }
+
+ if (iommu_is_off) {
+ if (base >= 0x80000000ul)
+ continue;
+ if ((base + size) > 0x80000000ul)
+ size = 0x80000000ul - base;
+ }
+
+ DBG("Adding: %llx -> %llx\n", base, size);
+ if (validate_mem_limit(base, &size))
+ memblock_add(base, size);
+ } while (--rngs);
+}
+
+int __init platform_early_init_dt_scan_memory_ppc(unsigned long node,
+ const char *uname,
+ int depth, void *data)
+{
+ if (depth == 1 &&
+ strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) {
+ walk_drmem_lmbs_early(node, early_init_drmem_lmb);
+ return 0;
+ }
+
+ return -ENODEV;
+}
More information about the Linuxppc-dev
mailing list