diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
index 933aefe77..86ec85bfc 100644
--- a/conf/powerpc-ieee1275.rmk
+++ b/conf/powerpc-ieee1275.rmk
@@ -67,7 +67,7 @@ datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For relocator.mod.
pkglib_MODULES += relocator.mod
-relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/relocator.c lib/$(target_cpu)/relocator_asm.S
+relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/relocator.c lib/$(target_cpu)/relocator_asm.S lib/ieee1275/relocator.c
relocator_mod_CFLAGS = $(COMMON_CFLAGS)
relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/tests.rmk b/conf/tests.rmk
index d48bc3dd9..e86c315d3 100644
--- a/conf/tests.rmk
+++ b/conf/tests.rmk
@@ -2,7 +2,7 @@
# For grub-shell
grub-shell: tests/util/grub-shell.in config.status
- ./config.status --file=$@:$<
+ ./config.status --file=-:$< | sed -e 's,@pkglib_DATA@,$(pkglib_DATA),g' > $@
chmod +x $@
check_SCRIPTS += grub-shell
CLEANFILES += grub-shell
diff --git a/include/grub/powerpc/memory.h b/include/grub/powerpc/memory.h
new file mode 100644
index 000000000..b748f33c5
--- /dev/null
+++ b/include/grub/powerpc/memory.h
@@ -0,0 +1,47 @@
+/* memory.h - describe the memory map */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ * GRUB 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+
+#ifndef GRUB_MEMORY_CPU_HEADER
+#define GRUB_MEMORY_CPU_HEADER 1
+
+#ifndef ASM_FILE
+
+typedef grub_addr_t grub_phys_addr_t;
+
+static inline grub_phys_addr_t
+grub_vtop (void *a)
+{
+ return (grub_phys_addr_t) a;
+}
+
+static inline void *
+grub_map_memory (grub_phys_addr_t a, grub_size_t size __attribute__ ((unused)))
+{
+ return (void *) a;
+}
+
+static inline void
+grub_unmap_memory (void *a __attribute__ ((unused)),
+ grub_size_t size __attribute__ ((unused)))
+{
+}
+
+#endif
+
+#endif /* ! GRUB_MEMORY_CPU_HEADER */
diff --git a/include/grub/relocator_private.h b/include/grub/relocator_private.h
index 10e445bfe..1c563cb64 100644
--- a/include/grub/relocator_private.h
+++ b/include/grub/relocator_private.h
@@ -40,6 +40,8 @@ void grub_cpu_relocator_backward (void *rels, void *src, void *tgt,
grub_size_t size);
void grub_cpu_relocator_jumper (void *rels, grub_addr_t addr);
+/* Remark: GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT_LOG = 1 or 2
+ aren't supported. */
#ifdef GRUB_MACHINE_IEEE1275
#define GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS 1
#define GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT_LOG 0
@@ -50,6 +52,12 @@ void grub_cpu_relocator_jumper (void *rels, grub_addr_t addr);
#define GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS 0
#endif
+#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS && GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT_LOG != 0
+#define GRUB_RELOCATOR_HAVE_LEFTOVERS 1
+#else
+#define GRUB_RELOCATOR_HAVE_LEFTOVERS 0
+#endif
+
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
#define GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT (1 << GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT_LOG)
#endif
@@ -67,6 +75,8 @@ struct grub_relocator_mmap_event
/* To track the regions already in heap. */
FIRMWARE_BLOCK_START = 6,
FIRMWARE_BLOCK_END = FIRMWARE_BLOCK_START | 1,
+#endif
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
REG_LEFTOVER_START = 8,
REG_LEFTOVER_END = REG_LEFTOVER_START | 1,
#endif
diff --git a/lib/powerpc/relocator.c b/lib/powerpc/relocator.c
index 9f5fc1c7f..85dfbeaf3 100644
--- a/lib/powerpc/relocator.c
+++ b/lib/powerpc/relocator.c
@@ -107,15 +107,15 @@ grub_err_t
grub_relocator32_boot (struct grub_relocator *rel,
struct grub_relocator32_state state)
{
- grub_addr_t target;
- void *src, *ptr;
+ void *ptr;
grub_err_t err;
- grub_addr_t relst;
+ void *relst;
grub_size_t relsize;
grub_size_t stateset_size = 32 * REGW_SIZEOF + JUMP_SIZEOF;
unsigned i;
+ grub_relocator_chunk_t ch;
- err = grub_relocator_alloc_chunk_align (rel, &src, &target, 0,
+ err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
(0xffffffff - stateset_size)
+ 1, stateset_size,
sizeof (grub_uint32_t),
@@ -123,12 +123,13 @@ grub_relocator32_boot (struct grub_relocator *rel,
if (err)
return err;
- ptr = src;
+ ptr = get_virtual_current_address (ch);
for (i = 0; i < 32; i++)
write_reg (i, state.gpr[i], &ptr);
write_jump (&ptr);
- err = grub_relocator_prepare_relocs (rel, target, &relst, &relsize);
+ err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
+ &relst, &relsize);
if (err)
return err;
diff --git a/lib/relocator.c b/lib/relocator.c
index 4c180e72a..6fbdb71d7 100644
--- a/lib/relocator.c
+++ b/lib/relocator.c
@@ -45,7 +45,9 @@ struct grub_relocator_subchunk
grub_size_t size;
grub_size_t pre_size;
struct grub_relocator_extra_block *extra;
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
struct grub_relocator_fw_leftover *pre, *post;
+#endif
};
struct grub_relocator_chunk
@@ -67,7 +69,7 @@ struct grub_relocator_extra_block
grub_phys_addr_t end;
};
-#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
struct grub_relocator_fw_leftover
{
struct grub_relocator_fw_leftover *next;
@@ -241,7 +243,7 @@ allocate_inreg (grub_phys_addr_t paddr, grub_size_t size,
}
}
-#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
static void
check_leftover (struct grub_relocator_fw_leftover *lo)
{
@@ -367,6 +369,7 @@ free_subchunk (const struct grub_relocator_subchunk *subchu)
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT);
if (fstart < fend)
grub_relocator_firmware_free_region (fstart, fend - fstart);
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
if (subchu->pre)
{
int off = subchu->start - fstart
@@ -384,6 +387,7 @@ free_subchunk (const struct grub_relocator_subchunk *subchu)
subchu->pre->freebytes[off / 8] |= ((1 << (8 - (off % 8))) - 1);
check_leftover (subchu->post);
}
+#endif
*subchu->extra->prev = subchu->extra->next;
grub_free (subchu->extra);
}
@@ -450,7 +454,9 @@ malloc_in_range (struct grub_relocator *rel,
maxevents += 2;
maxevents += grub_relocator_firmware_get_max_events ();
+#endif
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
{
struct grub_relocator_fw_leftover *cur;
for (cur = leftovers; cur; cur = cur->next)
@@ -500,8 +506,8 @@ malloc_in_range (struct grub_relocator *rel,
for (r = grub_mm_base; r; r = r->next)
{
grub_dprintf ("relocator", "Blocking at 0x%lx-0x%lx\n",
- (grub_addr_t) r - r->pre_size,
- (grub_addr_t) (r + 1) + r->size);
+ (unsigned long) r - r->pre_size,
+ (unsigned long) (r + 1) + r->size);
events[N].type = FIRMWARE_BLOCK_START;
events[N].pos = (grub_addr_t) r - r->pre_size;
N++;
@@ -514,7 +520,7 @@ malloc_in_range (struct grub_relocator *rel,
for (cur = extra_blocks; cur; cur = cur->next)
{
grub_dprintf ("relocator", "Blocking at 0x%lx-0x%lx\n",
- cur->start, cur->end);
+ (unsigned long) cur->start, (unsigned long) cur->end);
events[N].type = FIRMWARE_BLOCK_START;
events[N].pos = cur->start;
N++;
@@ -526,6 +532,7 @@ malloc_in_range (struct grub_relocator *rel,
N += grub_relocator_firmware_fill_events (events + N);
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
{
struct grub_relocator_fw_leftover *cur;
for (cur = leftovers; cur; cur = cur->next)
@@ -552,6 +559,7 @@ malloc_in_range (struct grub_relocator *rel,
}
}
}
+#endif
#endif
/* No malloc from this point. */
@@ -636,7 +644,11 @@ malloc_in_range (struct grub_relocator *rel,
/* Now events are nicely sorted. */
{
int nstarted = 0, ncollisions = 0, nstartedfw = 0, nblockfw = 0;
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
int nlefto = 0;
+#else
+ const int nlefto = 0;
+#endif
grub_addr_t starta = 0;
int numstarted;
for (j = from_low_priv ? 0 : N - 1; from_low_priv ? j < N : (j + 1);
@@ -663,6 +675,9 @@ malloc_in_range (struct grub_relocator *rel,
case FIRMWARE_BLOCK_END:
nblockfw--;
break;
+#endif
+
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
case REG_LEFTOVER_START:
nlefto++;
break;
@@ -794,7 +809,8 @@ malloc_in_range (struct grub_relocator *rel,
= ALIGN_UP (alloc_end,
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT);
grub_dprintf ("relocator", "requesting %lx-%lx\n",
- fstart, fend);
+ (unsigned long) fstart,
+ (unsigned long) fend);
/* The failure here can be very expensive. */
if (!grub_relocator_firmware_alloc_region (fstart,
fend - fstart))
@@ -807,6 +823,9 @@ malloc_in_range (struct grub_relocator *rel,
}
break;
}
+#endif
+
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
case CHUNK_TYPE_LEFTOVER:
{
unsigned offstart = alloc_start
@@ -857,14 +876,6 @@ malloc_in_range (struct grub_relocator *rel,
fwin--;
break;
- case REG_LEFTOVER_START:
- fwlefto++;
- break;
-
- case REG_LEFTOVER_END:
- fwlefto--;
- break;
-
case FIRMWARE_BLOCK_START:
fwb++;
break;
@@ -873,6 +884,16 @@ malloc_in_range (struct grub_relocator *rel,
fwb--;
break;
#endif
+
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ case REG_LEFTOVER_START:
+ fwlefto++;
+ break;
+
+ case REG_LEFTOVER_END:
+ fwlefto--;
+ break;
+#endif
case COLLISION_START:
ncol++;
break;
@@ -971,8 +992,6 @@ malloc_in_range (struct grub_relocator *rel,
if (!oom && typepre == CHUNK_TYPE_FIRMWARE)
{
grub_addr_t fstart, fend;
- struct grub_relocator_fw_leftover *lo1 = NULL;
- struct grub_relocator_fw_leftover *lo2 = NULL;
fstart
= ALIGN_DOWN (alloc_start,
@@ -981,68 +1000,77 @@ malloc_in_range (struct grub_relocator *rel,
= ALIGN_UP (alloc_end,
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT);
- if (fstart != alloc_start)
- lo1 = grub_malloc (sizeof (*lo1));
- if (fend != alloc_end)
- lo2 = grub_malloc (sizeof (*lo2));
- if ((!lo1 && fstart != alloc_start)
- || (!lo2 && fend != alloc_end))
- {
- struct grub_relocator_extra_block *ne;
- grub_free (lo1);
- grub_free (lo2);
- lo1 = NULL;
- lo2 = NULL;
- oom = 1;
- grub_memcpy (&tofree, curschu, sizeof (tofree));
- ne = extra_blocks;
- extra_blocks = extra_blocks->next;
- grub_free (ne);
- }
- if (lo1)
- {
- lo1->quantstart = fstart;
- grub_memset (lo1->freebytes, 0xff,
- (alloc_start - fstart) / 8);
- lo1->freebytes[(alloc_start - fstart) / 8]
- = (1 << ((alloc_start - fstart) % 8)) - 1;
- grub_memset (lo1->freebytes
- + ((alloc_start - fstart) / 8) + 1, 0,
- sizeof (lo1->freebytes)
- - (alloc_start - fstart) / 8 - 1);
- lo1->next = leftovers;
- lo1->prev = &leftovers;
- if (leftovers)
- leftovers->prev = &lo1->next;
- leftovers = lo1;
- }
- if (lo2)
- {
- lo2->quantstart
- = fend - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT;
- grub_memset (lo2->freebytes, 0,
- (alloc_end - lo2->quantstart) / 8);
- lo2->freebytes[(alloc_end - lo2->quantstart) / 8]
- = ~((1 << ((alloc_end - lo2->quantstart) % 8)) - 1);
- grub_memset (lo2->freebytes
- + ((alloc_end - lo2->quantstart) / 8)
- + 1, 0, sizeof (lo2->freebytes)
- - (alloc_end - lo2->quantstart) / 8 - 1);
- lo2->prev = &leftovers;
- if (leftovers)
- leftovers->prev = &lo2->next;
- lo2->next = leftovers;
- leftovers = lo2;
- }
- curschu->pre = lo1;
- curschu->post = lo2;
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ {
+ struct grub_relocator_fw_leftover *lo1 = NULL;
+ struct grub_relocator_fw_leftover *lo2 = NULL;
+ if (fstart != alloc_start)
+ lo1 = grub_malloc (sizeof (*lo1));
+ if (fend != alloc_end)
+ lo2 = grub_malloc (sizeof (*lo2));
+ if ((!lo1 && fstart != alloc_start)
+ || (!lo2 && fend != alloc_end))
+ {
+ struct grub_relocator_extra_block *ne;
+ grub_free (lo1);
+ grub_free (lo2);
+ lo1 = NULL;
+ lo2 = NULL;
+ oom = 1;
+ grub_memcpy (&tofree, curschu, sizeof (tofree));
+ ne = extra_blocks;
+ extra_blocks = extra_blocks->next;
+ grub_free (ne);
+ }
+ if (lo1)
+ {
+ lo1->quantstart = fstart;
+ grub_memset (lo1->freebytes, 0xff,
+ (alloc_start - fstart) / 8);
+ lo1->freebytes[(alloc_start - fstart) / 8]
+ = (1 << ((alloc_start - fstart) % 8)) - 1;
+ grub_memset (lo1->freebytes
+ + ((alloc_start - fstart) / 8) + 1, 0,
+ sizeof (lo1->freebytes)
+ - (alloc_start - fstart) / 8 - 1);
+ lo1->next = leftovers;
+ lo1->prev = &leftovers;
+ if (leftovers)
+ leftovers->prev = &lo1->next;
+ leftovers = lo1;
+ }
+ if (lo2)
+ {
+ lo2->quantstart
+ = fend - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT;
+ grub_memset (lo2->freebytes, 0,
+ (alloc_end - lo2->quantstart) / 8);
+ lo2->freebytes[(alloc_end - lo2->quantstart) / 8]
+ = ~((1 << ((alloc_end - lo2->quantstart) % 8)) - 1);
+ grub_memset (lo2->freebytes
+ + ((alloc_end - lo2->quantstart) / 8)
+ + 1, 0, sizeof (lo2->freebytes)
+ - (alloc_end - lo2->quantstart) / 8 - 1);
+ lo2->prev = &leftovers;
+ if (leftovers)
+ leftovers->prev = &lo2->next;
+ lo2->next = leftovers;
+ leftovers = lo2;
+ }
+ curschu->pre = lo1;
+ curschu->post = lo2;
+ }
+#endif
}
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
if (typepre == CHUNK_TYPE_LEFTOVER)
{
curschu->pre = events[last_start].leftover;
curschu->post = events[last_start].leftover;
}
+#endif
+
#endif
if (!oom)
cural++;
@@ -1077,14 +1105,6 @@ malloc_in_range (struct grub_relocator *rel,
fwin--;
break;
- case REG_LEFTOVER_START:
- fwlefto++;
- break;
-
- case REG_LEFTOVER_END:
- fwlefto--;
- break;
-
case FIRMWARE_BLOCK_START:
fwb++;
break;
@@ -1093,6 +1113,16 @@ malloc_in_range (struct grub_relocator *rel,
fwb--;
break;
#endif
+
+#if GRUB_RELOCATOR_HAVE_LEFTOVERS
+ case REG_LEFTOVER_START:
+ fwlefto++;
+ break;
+
+ case REG_LEFTOVER_END:
+ fwlefto--;
+ break;
+#endif
case COLLISION_START:
ncol++;
break;
diff --git a/loader/powerpc/ieee1275/linux.c b/loader/powerpc/ieee1275/linux.c
index 930c0cb41..c9feec975 100644
--- a/loader/powerpc/ieee1275/linux.c
+++ b/loader/powerpc/ieee1275/linux.c
@@ -24,7 +24,6 @@
#include
#include
#include
-#include
#include
#include