s390/mem_detect: move memory detection code to mm folder
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Fri, 26 Apr 2013 14:47:28 +0000 (16:47 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 2 May 2013 13:50:22 +0000 (15:50 +0200)
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/kernel/Makefile
arch/s390/kernel/mem_detect.c [deleted file]
arch/s390/mm/Makefile
arch/s390/mm/mem_detect.c [new file with mode: 0644]

index 1386fcaf4ef6c7854838df1563604bca1d74603a..4bb2a46561631ab361c027fdcfc8a1dfd0504cb5 100644 (file)
@@ -30,7 +30,7 @@ CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
 
 obj-y  := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o
 obj-y  += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o
-obj-y  += debug.o irq.o ipl.o dis.o diag.o mem_detect.o sclp.o vdso.o
+obj-y  += debug.o irq.o ipl.o dis.o diag.o sclp.o vdso.o
 obj-y  += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o
 obj-y  += dumpstack.o
 
diff --git a/arch/s390/kernel/mem_detect.c b/arch/s390/kernel/mem_detect.c
deleted file mode 100644 (file)
index 22d502e..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright IBM Corp. 2008, 2009
- *
- * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/ipl.h>
-#include <asm/sclp.h>
-#include <asm/setup.h>
-
-#define ADDR2G (1ULL << 31)
-
-static void find_memory_chunks(struct mem_chunk chunk[])
-{
-       unsigned long long memsize, rnmax, rzm;
-       unsigned long addr = 0, size;
-       int i = 0, type;
-
-       rzm = sclp_get_rzm();
-       rnmax = sclp_get_rnmax();
-       memsize = rzm * rnmax;
-       if (!rzm)
-               rzm = 1ULL << 17;
-       if (sizeof(long) == 4) {
-               rzm = min(ADDR2G, rzm);
-               memsize = memsize ? min(ADDR2G, memsize) : ADDR2G;
-       }
-       do {
-               size = 0;
-               type = tprot(addr);
-               do {
-                       size += rzm;
-                       if (memsize && addr + size >= memsize)
-                               break;
-               } while (type == tprot(addr + size));
-               if (type == CHUNK_READ_WRITE || type == CHUNK_READ_ONLY) {
-                       chunk[i].addr = addr;
-                       chunk[i].size = size;
-                       chunk[i].type = type;
-                       i++;
-               }
-               addr += size;
-       } while (addr < memsize && i < MEMORY_CHUNKS);
-}
-
-void detect_memory_layout(struct mem_chunk chunk[])
-{
-       unsigned long flags, cr0;
-
-       memset(chunk, 0, MEMORY_CHUNKS * sizeof(struct mem_chunk));
-       /* Disable IRQs, DAT and low address protection so tprot does the
-        * right thing and we don't get scheduled away with low address
-        * protection disabled.
-        */
-       flags = __arch_local_irq_stnsm(0xf8);
-       __ctl_store(cr0, 0, 0);
-       __ctl_clear_bit(0, 28);
-       find_memory_chunks(chunk);
-       __ctl_load(cr0, 0, 0);
-       arch_local_irq_restore(flags);
-}
-EXPORT_SYMBOL(detect_memory_layout);
-
-/*
- * Move memory chunks array from index "from" to index "to"
- */
-static void mem_chunk_move(struct mem_chunk chunk[], int to, int from)
-{
-       int cnt = MEMORY_CHUNKS - to;
-
-       memmove(&chunk[to], &chunk[from], cnt * sizeof(struct mem_chunk));
-}
-
-/*
- * Initialize memory chunk
- */
-static void mem_chunk_init(struct mem_chunk *chunk, unsigned long addr,
-                          unsigned long size, int type)
-{
-       chunk->type = type;
-       chunk->addr = addr;
-       chunk->size = size;
-}
-
-/*
- * Create memory hole with given address, size, and type
- */
-void create_mem_hole(struct mem_chunk chunk[], unsigned long addr,
-                    unsigned long size, int type)
-{
-       unsigned long lh_start, lh_end, lh_size, ch_start, ch_end, ch_size;
-       int i, ch_type;
-
-       for (i = 0; i < MEMORY_CHUNKS; i++) {
-               if (chunk[i].size == 0)
-                       continue;
-
-               /* Define chunk properties */
-               ch_start = chunk[i].addr;
-               ch_size = chunk[i].size;
-               ch_end = ch_start + ch_size - 1;
-               ch_type = chunk[i].type;
-
-               /* Is memory chunk hit by memory hole? */
-               if (addr + size <= ch_start)
-                       continue; /* No: memory hole in front of chunk */
-               if (addr > ch_end)
-                       continue; /* No: memory hole after chunk */
-
-               /* Yes: Define local hole properties */
-               lh_start = max(addr, chunk[i].addr);
-               lh_end = min(addr + size - 1, ch_end);
-               lh_size = lh_end - lh_start + 1;
-
-               if (lh_start == ch_start && lh_end == ch_end) {
-                       /* Hole covers complete memory chunk */
-                       mem_chunk_init(&chunk[i], lh_start, lh_size, type);
-               } else if (lh_end == ch_end) {
-                       /* Hole starts in memory chunk and convers chunk end */
-                       mem_chunk_move(chunk, i + 1, i);
-                       mem_chunk_init(&chunk[i], ch_start, ch_size - lh_size,
-                                      ch_type);
-                       mem_chunk_init(&chunk[i + 1], lh_start, lh_size, type);
-                       i += 1;
-               } else if (lh_start == ch_start) {
-                       /* Hole ends in memory chunk */
-                       mem_chunk_move(chunk, i + 1, i);
-                       mem_chunk_init(&chunk[i], lh_start, lh_size, type);
-                       mem_chunk_init(&chunk[i + 1], lh_end + 1,
-                                      ch_size - lh_size, ch_type);
-                       break;
-               } else {
-                       /* Hole splits memory chunk */
-                       mem_chunk_move(chunk, i + 2, i);
-                       mem_chunk_init(&chunk[i], ch_start,
-                                      lh_start - ch_start, ch_type);
-                       mem_chunk_init(&chunk[i + 1], lh_start, lh_size, type);
-                       mem_chunk_init(&chunk[i + 2], lh_end + 1,
-                                      ch_end - lh_end, ch_type);
-                       break;
-               }
-       }
-}
index 640bea12303c0a659bcbb235bf191aaee8da4c62..839592ca265cdb620ddbe1c0505e9d9bbe4d428c 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 obj-y          := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o
-obj-y          += page-states.o gup.o extable.o pageattr.o
+obj-y          += page-states.o gup.o extable.o pageattr.o mem_detect.o
 
 obj-$(CONFIG_CMM)              += cmm.o
 obj-$(CONFIG_HUGETLB_PAGE)     += hugetlbpage.o
diff --git a/arch/s390/mm/mem_detect.c b/arch/s390/mm/mem_detect.c
new file mode 100644 (file)
index 0000000..22d502e
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright IBM Corp. 2008, 2009
+ *
+ * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/ipl.h>
+#include <asm/sclp.h>
+#include <asm/setup.h>
+
+#define ADDR2G (1ULL << 31)
+
+static void find_memory_chunks(struct mem_chunk chunk[])
+{
+       unsigned long long memsize, rnmax, rzm;
+       unsigned long addr = 0, size;
+       int i = 0, type;
+
+       rzm = sclp_get_rzm();
+       rnmax = sclp_get_rnmax();
+       memsize = rzm * rnmax;
+       if (!rzm)
+               rzm = 1ULL << 17;
+       if (sizeof(long) == 4) {
+               rzm = min(ADDR2G, rzm);
+               memsize = memsize ? min(ADDR2G, memsize) : ADDR2G;
+       }
+       do {
+               size = 0;
+               type = tprot(addr);
+               do {
+                       size += rzm;
+                       if (memsize && addr + size >= memsize)
+                               break;
+               } while (type == tprot(addr + size));
+               if (type == CHUNK_READ_WRITE || type == CHUNK_READ_ONLY) {
+                       chunk[i].addr = addr;
+                       chunk[i].size = size;
+                       chunk[i].type = type;
+                       i++;
+               }
+               addr += size;
+       } while (addr < memsize && i < MEMORY_CHUNKS);
+}
+
+void detect_memory_layout(struct mem_chunk chunk[])
+{
+       unsigned long flags, cr0;
+
+       memset(chunk, 0, MEMORY_CHUNKS * sizeof(struct mem_chunk));
+       /* Disable IRQs, DAT and low address protection so tprot does the
+        * right thing and we don't get scheduled away with low address
+        * protection disabled.
+        */
+       flags = __arch_local_irq_stnsm(0xf8);
+       __ctl_store(cr0, 0, 0);
+       __ctl_clear_bit(0, 28);
+       find_memory_chunks(chunk);
+       __ctl_load(cr0, 0, 0);
+       arch_local_irq_restore(flags);
+}
+EXPORT_SYMBOL(detect_memory_layout);
+
+/*
+ * Move memory chunks array from index "from" to index "to"
+ */
+static void mem_chunk_move(struct mem_chunk chunk[], int to, int from)
+{
+       int cnt = MEMORY_CHUNKS - to;
+
+       memmove(&chunk[to], &chunk[from], cnt * sizeof(struct mem_chunk));
+}
+
+/*
+ * Initialize memory chunk
+ */
+static void mem_chunk_init(struct mem_chunk *chunk, unsigned long addr,
+                          unsigned long size, int type)
+{
+       chunk->type = type;
+       chunk->addr = addr;
+       chunk->size = size;
+}
+
+/*
+ * Create memory hole with given address, size, and type
+ */
+void create_mem_hole(struct mem_chunk chunk[], unsigned long addr,
+                    unsigned long size, int type)
+{
+       unsigned long lh_start, lh_end, lh_size, ch_start, ch_end, ch_size;
+       int i, ch_type;
+
+       for (i = 0; i < MEMORY_CHUNKS; i++) {
+               if (chunk[i].size == 0)
+                       continue;
+
+               /* Define chunk properties */
+               ch_start = chunk[i].addr;
+               ch_size = chunk[i].size;
+               ch_end = ch_start + ch_size - 1;
+               ch_type = chunk[i].type;
+
+               /* Is memory chunk hit by memory hole? */
+               if (addr + size <= ch_start)
+                       continue; /* No: memory hole in front of chunk */
+               if (addr > ch_end)
+                       continue; /* No: memory hole after chunk */
+
+               /* Yes: Define local hole properties */
+               lh_start = max(addr, chunk[i].addr);
+               lh_end = min(addr + size - 1, ch_end);
+               lh_size = lh_end - lh_start + 1;
+
+               if (lh_start == ch_start && lh_end == ch_end) {
+                       /* Hole covers complete memory chunk */
+                       mem_chunk_init(&chunk[i], lh_start, lh_size, type);
+               } else if (lh_end == ch_end) {
+                       /* Hole starts in memory chunk and convers chunk end */
+                       mem_chunk_move(chunk, i + 1, i);
+                       mem_chunk_init(&chunk[i], ch_start, ch_size - lh_size,
+                                      ch_type);
+                       mem_chunk_init(&chunk[i + 1], lh_start, lh_size, type);
+                       i += 1;
+               } else if (lh_start == ch_start) {
+                       /* Hole ends in memory chunk */
+                       mem_chunk_move(chunk, i + 1, i);
+                       mem_chunk_init(&chunk[i], lh_start, lh_size, type);
+                       mem_chunk_init(&chunk[i + 1], lh_end + 1,
+                                      ch_size - lh_size, ch_type);
+                       break;
+               } else {
+                       /* Hole splits memory chunk */
+                       mem_chunk_move(chunk, i + 2, i);
+                       mem_chunk_init(&chunk[i], ch_start,
+                                      lh_start - ch_start, ch_type);
+                       mem_chunk_init(&chunk[i + 1], lh_start, lh_size, type);
+                       mem_chunk_init(&chunk[i + 2], lh_end + 1,
+                                      ch_end - lh_end, ch_type);
+                       break;
+               }
+       }
+}