[patch 05/12] kexec-tools: mipsel: Remove #ifdef __MIPSEL__ from kexec/kexec.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On all architectures except mipsel add_buffer() expects
add_segment() to work with the virtual address passed.
On mipsel it is expected that add_segment() converts
the virtual address to a physical address first.
add_buffer_virt() is porvided on mipsel for the handful
of cases that don't want the address to be converted.

This patch maintains that behaviour, but without the need for #ifdef
__MIPSEL__ from kexec/kexec.c and much duplicated code.

Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>

---

 kexec/arch/mipsel/kexec-mipsel.c |   26 +++++++
 kexec/kexec.c                    |  137 +++++++++-----------------------------
 kexec/kexec.h                    |    9 ++
 3 files changed, 71 insertions(+), 101 deletions(-)

Index: kexec-tools-testing-mips/kexec/arch/mipsel/kexec-mipsel.c
===================================================================
--- kexec-tools-testing-mips.orig/kexec/arch/mipsel/kexec-mipsel.c	2008-03-06 18:39:25.000000000 +0900
+++ kexec-tools-testing-mips/kexec/arch/mipsel/kexec-mipsel.c	2008-03-06 18:44:54.000000000 +0900
@@ -165,3 +165,29 @@ int is_crashkernel_mem_reserved(void)
 	return 1;
 }
 
+unsigned long virt_to_phys(unsigned long addr)
+{
+	return addr - 0x80000000;
+}
+
+/*
+ * add_segment() should convert base to a physical address on mipsel,
+ * while the default is just to work with base as is */
+void add_segment(struct kexec_info *info, const void *buf, size_t bufsz,
+		 unsigned long base, size_t memsz)
+{
+	add_segment_phys_virt(info, buf, bufsz, base, memsz, 1);
+}
+
+/*
+ * add_buffer() should convert base to a physical address on mipsel,
+ * while the default is just to work with base as is */
+unsigned long add_buffer(struct kexec_info *info, const void *buf,
+			 unsigned long bufsz, unsigned long memsz,
+			 unsigned long buf_align, unsigned long buf_min,
+			 unsigned long buf_max, int buf_end)
+{
+	return add_buffer_phys_virt(info, buf, bufsz, memsz, buf_align,
+				    buf_min, buf_max, buf_end, 1);
+}
+
Index: kexec-tools-testing-mips/kexec/kexec.c
===================================================================
--- kexec-tools-testing-mips.orig/kexec/kexec.c	2008-03-06 18:39:25.000000000 +0900
+++ kexec-tools-testing-mips/kexec/kexec.c	2008-03-06 18:39:34.000000000 +0900
@@ -44,10 +44,6 @@
 #include "kexec-sha256.h"
 #include <arch/options.h>
 
-#ifdef __MIPSEL__
-#define virt_to_phys(X) ((X) - 0x80000000)
-#endif
-
 unsigned long long mem_min = 0;
 unsigned long long mem_max = ULONG_MAX;
 
@@ -289,16 +285,18 @@ unsigned long locate_hole(struct kexec_i
 	return hole_base;
 }
 
-void add_segment(struct kexec_info *info,
+unsigned long __attribute__((weak)) virt_to_phys(unsigned long addr)
+{
+	abort();
+}
+
+void add_segment_phys_virt(struct kexec_info *info,
 	const void *buf, size_t bufsz,
-	unsigned long base, size_t memsz)
+	unsigned long base, size_t memsz, int phys)
 {
 	unsigned long last;
 	size_t size;
 	int pagesize;
-#ifdef __MIPSEL__
-	unsigned long base_phys;
-#endif
 
 	if (bufsz > memsz) {
 		bufsz = memsz;
@@ -312,9 +310,6 @@ void add_segment(struct kexec_info *info
 	pagesize = getpagesize();
 	memsz = (memsz + (pagesize - 1)) & ~(pagesize - 1);
 
-#ifdef __MIPSEL__
-	base_phys=virt_to_phys(base);
-#endif
 	/* Verify base is pagesize aligned.
 	 * Finding a way to cope with this problem
 	 * is important but for now error so at least
@@ -325,29 +320,20 @@ void add_segment(struct kexec_info *info
 		die("Base address: %x is not page aligned\n", base);
 	}
 
-#ifdef __MIPSEL__
-	last = base_phys + memsz -1;
-	if (!valid_memory_range(info, base_phys, last)) {
-		die("Invalid memory segment %p - %p\n",
-			(void *)base_phys, (void *)last);
-	}
-#else
+	if (phys)
+		base = virt_to_phys(base);
+
 	last = base + memsz -1;
 	if (!valid_memory_range(info, base, last)) {
 		die("Invalid memory segment %p - %p\n",
 			(void *)base, (void *)last);
 	}
-#endif
 
 	size = (info->nr_segments + 1) * sizeof(info->segment[0]);
 	info->segment = xrealloc(info->segment, size);
 	info->segment[info->nr_segments].buf   = buf;
 	info->segment[info->nr_segments].bufsz = bufsz;
-#ifdef __MIPSEL__
-	info->segment[info->nr_segments].mem   = (void *)base_phys;
-#else
 	info->segment[info->nr_segments].mem   = (void *)base;
-#endif
 	info->segment[info->nr_segments].memsz = memsz;
 	info->nr_segments++;
 	if (info->nr_segments > KEXEC_MAX_SEGMENTS) {
@@ -356,61 +342,17 @@ void add_segment(struct kexec_info *info
 	}
 }
 
-#ifdef __MIPSEL__
-void add_segment_virt(struct kexec_info *info,
-	const void *buf, size_t bufsz,
-	unsigned long base, size_t memsz)
+void __attribute__((weak)) add_segment(struct kexec_info *info,
+				       const void *buf, size_t bufsz,
+				       unsigned long base, size_t memsz)
 {
-	unsigned long last;
-	size_t size;
-	int pagesize;
-
-	if (bufsz > memsz) {
-		bufsz = memsz;
-	}
-	/* Forget empty segments */
-	if (memsz == 0) {
-		return;
-	}
-
-	/* Round memsz up to a multiple of pagesize */
-	pagesize = getpagesize();
-	memsz = (memsz + (pagesize - 1)) & ~(pagesize - 1);
-
-	/* Verify base is pagesize aligned.
-	 * Finding a way to cope with this problem
-	 * is important but for now error so at least
-	 * we are not surprised by the code doing the wrong
-	 * thing.
-	 */
-	if (base & (pagesize -1)) {
-		die("Base address: %x is not page aligned\n", base);
-	}
-	
-	last = base + memsz -1;
-	if (!valid_memory_range(info, base, last)) {
-		die("Invalid memory segment %p - %p\n",
-			(void *)base, (void *)last);
-	}
-	
-	size = (info->nr_segments + 1) * sizeof(info->segment[0]);
-	info->segment = xrealloc(info->segment, size);
-	info->segment[info->nr_segments].buf   = buf;
-	info->segment[info->nr_segments].bufsz = bufsz;
-	info->segment[info->nr_segments].mem   = (void *)base;
-	info->segment[info->nr_segments].memsz = memsz;
-	info->nr_segments++;
-	if (info->nr_segments > KEXEC_MAX_SEGMENTS) {
-		fprintf(stderr, "Warning: kernel segment limit reached. "
-			"This will likely fail\n");
-	}
+	return add_segment_phys_virt(info, buf, bufsz, base, memsz, 0);
 }
-#endif
 
-unsigned long add_buffer(struct kexec_info *info,
+unsigned long add_buffer_phys_virt(struct kexec_info *info,
 	const void *buf, unsigned long bufsz, unsigned long memsz,
 	unsigned long buf_align, unsigned long buf_min, unsigned long buf_max,
-	int buf_end)
+	int buf_end, int phys)
 {
 	unsigned long base;
 	int result;
@@ -430,38 +372,31 @@ unsigned long add_buffer(struct kexec_in
 		die("locate_hole failed\n");
 	}
 	
-	add_segment(info, buf, bufsz, base, memsz);
+	add_segment_phys_virt(info, buf, bufsz, base, memsz, phys);
 	return base;
 }
 
-#ifdef __MIPSEL__
-unsigned long add_buffer_virt(struct kexec_info *info,
-	const void *buf, unsigned long bufsz, unsigned long memsz,
-	unsigned long buf_align, unsigned long buf_min, unsigned long buf_max,
-	int buf_end)
+unsigned long add_buffer_virt(struct kexec_info *info, const void *buf,
+			      unsigned long bufsz, unsigned long memsz,
+			      unsigned long buf_align, unsigned long buf_min,
+			      unsigned long buf_max, int buf_end)
+{
+	return add_buffer_phys_virt(info, buf, bufsz, memsz, buf_align,
+				    buf_min, buf_max, buf_end, 0);
+}
+
+unsigned long __attribute__((weak)) add_buffer(struct kexec_info *info,
+					       const void *buf,
+					       unsigned long bufsz,
+					       unsigned long memsz,
+					       unsigned long buf_align,
+					       unsigned long buf_min,
+					       unsigned long buf_max,
+					       int buf_end)
 {
-	unsigned long base;
-	int result;
-	int pagesize;
-
-	result = sort_segments(info);
-	if (result < 0) {
-		die("sort_segments failed\n");
-	}
-
-	/* Round memsz up to a multiple of pagesize */
-	pagesize = getpagesize();
-	memsz = (memsz + (pagesize - 1)) & ~(pagesize - 1);
-
-	base = locate_hole(info, memsz, buf_align, buf_min, buf_max, buf_end);
-	if (base == ULONG_MAX) {
-		die("locate_hole failed\n");
-	}
-
-	add_segment_virt(info, buf, bufsz, base, memsz);
-	return base;
+	return add_buffer_virt(info, buf, bufsz, memsz, buf_align,
+			       buf_min, buf_max, buf_end);
 }
-#endif
 
 char *slurp_file(const char *filename, off_t *r_size)
 {
Index: kexec-tools-testing-mips/kexec/kexec.h
===================================================================
--- kexec-tools-testing-mips.orig/kexec/kexec.h	2008-03-06 18:39:25.000000000 +0900
+++ kexec-tools-testing-mips/kexec/kexec.h	2008-03-06 18:45:53.000000000 +0900
@@ -188,12 +188,24 @@ extern void *xrealloc(void *ptr, size_t 
 extern char *slurp_file(const char *filename, off_t *r_size);
 extern char *slurp_file_len(const char *filename, off_t size);
 extern char *slurp_decompress_file(const char *filename, off_t *r_size);
+extern unsigned long virt_to_phys(unsigned long addr);
 extern void add_segment(struct kexec_info *info,
 	const void *buf, size_t bufsz, unsigned long base, size_t memsz);
+extern void add_segment_phys_virt(struct kexec_info *info,
+	const void *buf, size_t bufsz, unsigned long base, size_t memsz,
+	int phys);
 extern unsigned long add_buffer(struct kexec_info *info,
 	const void *buf, unsigned long bufsz, unsigned long memsz,
 	unsigned long buf_align, unsigned long buf_min, unsigned long buf_max,
 	int buf_end);
+extern unsigned long add_buffer_virt(struct kexec_info *info,
+	const void *buf, unsigned long bufsz, unsigned long memsz,
+	unsigned long buf_align, unsigned long buf_min, unsigned long buf_max,
+	int buf_end);
+extern unsigned long add_buffer_phys_virt(struct kexec_info *info,
+	const void *buf, unsigned long bufsz, unsigned long memsz,
+	unsigned long buf_align, unsigned long buf_min, unsigned long buf_max,
+	int buf_end, int phys);
 
 extern unsigned char purgatory[];
 extern size_t purgatory_size;

-- 

-- 
Horms



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux