summaryrefslogtreecommitdiff
path: root/kexec/kexec.c
diff options
context:
space:
mode:
authorSimon Horman <horms@verge.net.au>2008-03-06 18:22:32 +0900
committerSimon Horman <horms@verge.net.au>2008-03-06 18:50:46 +0900
commit7513645154273c6e1a8678c17b37c5f3fad2b490 (patch)
treeffdf0321196671131161b7daf26de58fa8d16b69 /kexec/kexec.c
parent8eeb3f9cdab8ffc9c576f9258df9a74f218ba1dc (diff)
kexec-tools: mipsel: Remove #ifdef __MIPSEL__ from kexec/kexec.c
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@verge.net.au>
Diffstat (limited to 'kexec/kexec.c')
-rw-r--r--kexec/kexec.c135
1 files changed, 35 insertions, 100 deletions
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 04cefed..0647295 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -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_info *info,
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_info *info,
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)
{
- 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");
- }
+ return add_buffer_phys_virt(info, buf, bufsz, memsz, buf_align,
+ buf_min, buf_max, buf_end, 0);
+}
- add_segment_virt(info, buf, bufsz, base, memsz);
- return base;
+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)
+{
+ 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)
{