* [ppc patch] remove BAT mappings
@ 2004-10-15 22:35 Hollis Blanchard
2004-10-20 1:30 ` Hollis Blanchard
0 siblings, 1 reply; 4+ messages in thread
From: Hollis Blanchard @ 2004-10-15 22:35 UTC (permalink / raw)
To: grub-devel
This patch removes the use of BAT registers to perform virtual memory
translations. BATs are a convenient way to avoid dealing with page
tables, however, there are two problems:
- Old World Macs apparently do not consider the BAT registers when
performing /chosen/mmu "translate" calls. The Linux kernel requires
that the "translate" result be accurate.
(Given that New World Macs seem to have been booting ok without this, I
can only assume that New World firmware was fixed.)
- BATs have been removed from POWER4 and POWER5 processors, used in
pSeries servers.
Instead of performing large one-time mappings, we map what we need. We
do this by calling the "map" method of /chosen/mmu (after claiming the
space first).
I have tested this patch on Old World and New World Macintosh. With this
patch applied, Old World can successfully boot into Linux. :)
-Hollis
2004-10-15 Hollis Blanchard <hollis@penguinppc.org>
* boot/powerpc/ieee1275/cmain.c (cmain): Remove asm statements
which initialized BAT registers.
* boot/powerpc/ieee1275/ieee1275.c (IEEE1275_CALL_ENTRY_FN): Move
to include/grub/powerpc/ieee1275/ieee1275.h.
(grub_ieee1275_common_hdr): Likewise.
(INIT_IEEE1275_COMMON): Likewise.
* include/grub/powerpc/ieee1275/ieee1275.h (IEEE1275_CALL_ENTRY_FN):
Move from boot/powerpc/ieee1275/ieee1275.c.
(grub_ieee1275_common_hdr): Likewise.
(INIT_IEEE1275_COMMON): Likewise.
* kern/powerpc/ieee1275/openfw.c (grub_map): New function.
(grub_mapclaim): Likewise.
* loader/powerpc/ieee1275/linux.c (grub_load_linux): Use
grub_mapclaim instead of grub_ieee1275_claim. Assign linux_addr by
hand.
Index: boot/powerpc/ieee1275/cmain.c
===================================================================
RCS file: /cvsroot/grub/grub2/boot/powerpc/ieee1275/cmain.c,v
retrieving revision 1.3
diff -u -p -r1.3 cmain.c
--- boot/powerpc/ieee1275/cmain.c 12 Oct 2004 03:56:10 -0000 1.3
+++ boot/powerpc/ieee1275/cmain.c 15 Oct 2004 22:19:53 -0000
@@ -55,7 +55,6 @@ cmain (uint32_t r3, uint32_t r4 __attrib
char **argv, args[256];
grub_ieee1275_phandle_t chosen;
int argc = 0, actual;
- long batl, batu;
if (r5 == 0xdeadbeef)
{
@@ -81,27 +80,6 @@ cmain (uint32_t r3, uint32_t r4 __attrib
grub_ieee1275_entry_fn = (intptr_t (*)(void *)) r5;
}
- /* Initialize BAT registers to unmapped to not generate overlapping
- mappings below. */
- asm volatile ("mtibatu 0,%0" :: "r"(0));
- asm volatile ("mtibatu 1,%0" :: "r"(0));
- asm volatile ("mtibatu 2,%0" :: "r"(0));
- asm volatile ("mtibatu 3,%0" :: "r"(0));
- asm volatile ("mtdbatu 0,%0" :: "r"(0));
- asm volatile ("mtdbatu 1,%0" :: "r"(0));
- asm volatile ("mtdbatu 2,%0" :: "r"(0));
- asm volatile ("mtdbatu 3,%0" :: "r"(0));
-
- /* Set up initial BAT table to only map the lowest 256 MB area. */
- batl = 0x00000000 | 0x10 | 0x02;
- batu = 0x00000000 | 0x1ffc | 0x02;
-
- /* IBAT0 used for initial 256 MB segment */
- asm volatile ("mtibatl 3,%0; mtibatu 3,%1" :: "r" (batl), "r" (batu));
- /* DBAT0 used similar */
- asm volatile ("mtdbatl 3,%0; mtdbatu 3,%1" :: "r" (batl), "r" (batu));
- asm ("isync");
-
/* If any argument was passed to the kernel (us), they are
put in the bootargs property of /chosen. The string can
be null (just the nul-character), so check that the size
Index: boot/powerpc/ieee1275/ieee1275.c
===================================================================
RCS file: /cvsroot/grub/grub2/boot/powerpc/ieee1275/ieee1275.c,v
retrieving revision 1.7
diff -u -p -r1.7 ieee1275.c
--- boot/powerpc/ieee1275/ieee1275.c 13 Oct 2004 23:43:43 -0000 1.7
+++ boot/powerpc/ieee1275/ieee1275.c 15 Oct 2004 22:19:53 -0000
@@ -26,25 +26,6 @@
intptr_t (*grub_ieee1275_entry_fn) (void *);
-#ifndef IEEE1275_CALL_ENTRY_FN
-#define IEEE1275_CALL_ENTRY_FN(args) (*grub_ieee1275_entry_fn) (args)
-#endif
-
-/* All backcalls to the firmware is done by calling an entry function
- which was passed to us from the bootloader. When doing the backcall,
- a structure is passed which specifies what the firmware should do.
- NAME is the requested service. NR_INS and NR_OUTS is the number of
- passed arguments and the expected number of return values, resp. */
-struct grub_ieee1275_common_hdr
-{
- char *name;
- int nr_ins;
- int nr_outs;
-};
-
-#define INIT_IEEE1275_COMMON(p, xname, xins, xouts) \
- (p)->name = xname; (p)->nr_ins = xins; (p)->nr_outs = xouts
-
/* FIXME is this function needed? */
grub_uint32_t
grub_ieee1275_decode_int_4 (unsigned char *p)
Index: include/grub/powerpc/ieee1275/ieee1275.h
===================================================================
RCS file: /cvsroot/grub/grub2/include/grub/powerpc/ieee1275/ieee1275.h,v
retrieving revision 1.8
diff -u -p -r1.8 ieee1275.h
--- include/grub/powerpc/ieee1275/ieee1275.h 15 Oct 2004 02:29:11 -0000 1.8
+++ include/grub/powerpc/ieee1275/ieee1275.h 15 Oct 2004 22:19:54 -0000
@@ -39,6 +39,27 @@ struct grub_ieee1275_mem_region
unsigned int size;
};
+extern intptr_t (*grub_ieee1275_entry_fn) (void *);
+
+#ifndef IEEE1275_CALL_ENTRY_FN
+#define IEEE1275_CALL_ENTRY_FN(args) (*grub_ieee1275_entry_fn) (args)
+#endif
+
+/* All backcalls to the firmware is done by calling an entry function
+ which was passed to us from the bootloader. When doing the backcall,
+ a structure is passed which specifies what the firmware should do.
+ NAME is the requested service. NR_INS and NR_OUTS is the number of
+ passed arguments and the expected number of return values, resp. */
+struct grub_ieee1275_common_hdr
+{
+ char *name;
+ int nr_ins;
+ int nr_outs;
+};
+
+#define INIT_IEEE1275_COMMON(p, xname, xins, xouts) \
+ (p)->name = xname; (p)->nr_ins = xins; (p)->nr_outs = xouts
+
/* FIXME jrydberg: is this correct cell types? */
typedef intptr_t grub_ieee1275_ihandle_t;
typedef intptr_t grub_ieee1275_phandle_t;
@@ -103,6 +124,7 @@ grub_err_t EXPORT_FUNC(grub_devalias_ite
(int (*hook) (struct grub_ieee1275_devalias *alias));
grub_err_t EXPORT_FUNC(grub_children_iterate) (char *devpath,
int (*hook) (struct grub_ieee1275_devalias *alias));
+int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
void EXPORT_FUNC(abort) (void);
Index: kern/powerpc/ieee1275/openfw.c
===================================================================
RCS file: /cvsroot/grub/grub2/kern/powerpc/ieee1275/openfw.c,v
retrieving revision 1.3
diff -u -p -r1.3 openfw.c
--- kern/powerpc/ieee1275/openfw.c 13 Oct 2004 23:43:44 -0000 1.3
+++ kern/powerpc/ieee1275/openfw.c 15 Oct 2004 22:19:55 -0000
@@ -137,3 +137,57 @@ grub_devalias_iterate (int (*hook) (stru
return 0;
}
+
+/* Call the "map" method of /chosen/mmu. */
+int
+grub_map (grub_addr_t phys, grub_addr_t virt, grub_uint32_t size,
+ grub_uint8_t mode)
+{
+ struct map_args {
+ struct grub_ieee1275_common_hdr common;
+ char *method;
+ grub_ieee1275_ihandle_t ihandle;
+ grub_uint32_t mode;
+ grub_uint32_t size;
+ grub_uint32_t virt;
+ grub_uint32_t phys;
+ int catch_result;
+ } args;
+ grub_ieee1275_ihandle_t mmu;
+ grub_ieee1275_ihandle_t chosen;
+ int len;
+
+ grub_ieee1275_finddevice ("/chosen", &chosen);
+ if (chosen == 0)
+ return -1;
+
+ grub_ieee1275_get_property (chosen, "mmu", &mmu, sizeof mmu, &len);
+ if (len != sizeof mmu)
+ return -1;
+
+ INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1);
+ args.method = "map";
+ args.ihandle = mmu;
+ args.phys = phys;
+ args.virt = virt;
+ args.size = size;
+ args.mode = mode; /* Format is WIMG0PP. */
+
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
+ return -1;
+
+ return args.catch_result;
+}
+
+int
+grub_claimmap (grub_addr_t addr, grub_size_t size)
+{
+ if (grub_ieee1275_claim (addr, size, 0, 0))
+ return -1;
+ if (grub_map (addr, addr, size, 0x00))
+ {
+ grub_ieee1275_release (addr, size);
+ return -1;
+ }
+ return 0;
+}
Index: loader/powerpc/ieee1275/linux.c
===================================================================
RCS file: /cvsroot/grub/grub2/loader/powerpc/ieee1275/linux.c,v
retrieving revision 1.3
diff -u -p -r1.3 linux.c
--- loader/powerpc/ieee1275/linux.c 3 Oct 2004 09:19:10 -0000 1.3
+++ loader/powerpc/ieee1275/linux.c 15 Oct 2004 22:19:56 -0000
@@ -188,12 +188,13 @@ grub_load_linux (int argc, char *argv[])
/* Reserve memory for the kernel. */
linux_size += 0x100000;
- if (grub_ieee1275_claim (entry, linux_size, 0, &linux_addr) == -1)
+ if (grub_claimmap (entry, linux_size) == -1)
{
grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not claim memory");
goto fail;
}
-
+ linux_addr = entry;
+
/* Load every loadable segment in memory. */
for (i = 0; i < ehdr.e_phnum; i++)
{
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [ppc patch] remove BAT mappings
2004-10-15 22:35 [ppc patch] remove BAT mappings Hollis Blanchard
@ 2004-10-20 1:30 ` Hollis Blanchard
2004-10-20 8:57 ` Marco Gerards
0 siblings, 1 reply; 4+ messages in thread
From: Hollis Blanchard @ 2004-10-20 1:30 UTC (permalink / raw)
To: The development of GRUB 2
Any comments on this patch?
On Oct 15, 2004, at 5:35 PM, Hollis Blanchard wrote:
> This patch removes the use of BAT registers to perform virtual memory
> translations. BATs are a convenient way to avoid dealing with page
> tables, however, there are two problems:
> - Old World Macs apparently do not consider the BAT registers when
> performing /chosen/mmu "translate" calls. The Linux kernel requires
> that the "translate" result be accurate.
> (Given that New World Macs seem to have been booting ok without
> this, I
> can only assume that New World firmware was fixed.)
> - BATs have been removed from POWER4 and POWER5 processors, used in
> pSeries servers.
>
> Instead of performing large one-time mappings, we map what we need. We
> do this by calling the "map" method of /chosen/mmu (after claiming the
> space first).
>
> I have tested this patch on Old World and New World Macintosh. With
> this
> patch applied, Old World can successfully boot into Linux. :)
>
> -Hollis
>
> 2004-10-15 Hollis Blanchard <hollis@penguinppc.org>
>
> * boot/powerpc/ieee1275/cmain.c (cmain): Remove asm statements
> which initialized BAT registers.
> * boot/powerpc/ieee1275/ieee1275.c (IEEE1275_CALL_ENTRY_FN): Move
> to include/grub/powerpc/ieee1275/ieee1275.h.
> (grub_ieee1275_common_hdr): Likewise.
> (INIT_IEEE1275_COMMON): Likewise.
> * include/grub/powerpc/ieee1275/ieee1275.h (IEEE1275_CALL_ENTRY_FN):
> Move from boot/powerpc/ieee1275/ieee1275.c.
> (grub_ieee1275_common_hdr): Likewise.
> (INIT_IEEE1275_COMMON): Likewise.
> * kern/powerpc/ieee1275/openfw.c (grub_map): New function.
> (grub_mapclaim): Likewise.
> * loader/powerpc/ieee1275/linux.c (grub_load_linux): Use
> grub_mapclaim instead of grub_ieee1275_claim. Assign linux_addr by
> hand.
>
> Index: boot/powerpc/ieee1275/cmain.c
> ===================================================================
> RCS file: /cvsroot/grub/grub2/boot/powerpc/ieee1275/cmain.c,v
> retrieving revision 1.3
> diff -u -p -r1.3 cmain.c
> --- boot/powerpc/ieee1275/cmain.c 12 Oct 2004 03:56:10 -0000 1.3
> +++ boot/powerpc/ieee1275/cmain.c 15 Oct 2004 22:19:53 -0000
> @@ -55,7 +55,6 @@ cmain (uint32_t r3, uint32_t r4 __attrib
> char **argv, args[256];
> grub_ieee1275_phandle_t chosen;
> int argc = 0, actual;
> - long batl, batu;
>
> if (r5 == 0xdeadbeef)
> {
> @@ -81,27 +80,6 @@ cmain (uint32_t r3, uint32_t r4 __attrib
> grub_ieee1275_entry_fn = (intptr_t (*)(void *)) r5;
> }
>
> - /* Initialize BAT registers to unmapped to not generate overlapping
> - mappings below. */
> - asm volatile ("mtibatu 0,%0" :: "r"(0));
> - asm volatile ("mtibatu 1,%0" :: "r"(0));
> - asm volatile ("mtibatu 2,%0" :: "r"(0));
> - asm volatile ("mtibatu 3,%0" :: "r"(0));
> - asm volatile ("mtdbatu 0,%0" :: "r"(0));
> - asm volatile ("mtdbatu 1,%0" :: "r"(0));
> - asm volatile ("mtdbatu 2,%0" :: "r"(0));
> - asm volatile ("mtdbatu 3,%0" :: "r"(0));
> -
> - /* Set up initial BAT table to only map the lowest 256 MB area. */
> - batl = 0x00000000 | 0x10 | 0x02;
> - batu = 0x00000000 | 0x1ffc | 0x02;
> -
> - /* IBAT0 used for initial 256 MB segment */
> - asm volatile ("mtibatl 3,%0; mtibatu 3,%1" :: "r" (batl), "r"
> (batu));
> - /* DBAT0 used similar */
> - asm volatile ("mtdbatl 3,%0; mtdbatu 3,%1" :: "r" (batl), "r"
> (batu));
> - asm ("isync");
> -
> /* If any argument was passed to the kernel (us), they are
> put in the bootargs property of /chosen. The string can
> be null (just the nul-character), so check that the size
> Index: boot/powerpc/ieee1275/ieee1275.c
> ===================================================================
> RCS file: /cvsroot/grub/grub2/boot/powerpc/ieee1275/ieee1275.c,v
> retrieving revision 1.7
> diff -u -p -r1.7 ieee1275.c
> --- boot/powerpc/ieee1275/ieee1275.c 13 Oct 2004 23:43:43 -0000 1.7
> +++ boot/powerpc/ieee1275/ieee1275.c 15 Oct 2004 22:19:53 -0000
> @@ -26,25 +26,6 @@
>
> intptr_t (*grub_ieee1275_entry_fn) (void *);
>
> -#ifndef IEEE1275_CALL_ENTRY_FN
> -#define IEEE1275_CALL_ENTRY_FN(args) (*grub_ieee1275_entry_fn) (args)
> -#endif
> -
> -/* All backcalls to the firmware is done by calling an entry function
> - which was passed to us from the bootloader. When doing the
> backcall,
> - a structure is passed which specifies what the firmware should do.
> - NAME is the requested service. NR_INS and NR_OUTS is the number of
> - passed arguments and the expected number of return values, resp. */
> -struct grub_ieee1275_common_hdr
> -{
> - char *name;
> - int nr_ins;
> - int nr_outs;
> -};
> -
> -#define INIT_IEEE1275_COMMON(p, xname, xins, xouts) \
> - (p)->name = xname; (p)->nr_ins = xins; (p)->nr_outs = xouts
> -
> /* FIXME is this function needed? */
> grub_uint32_t
> grub_ieee1275_decode_int_4 (unsigned char *p)
> Index: include/grub/powerpc/ieee1275/ieee1275.h
> ===================================================================
> RCS file:
> /cvsroot/grub/grub2/include/grub/powerpc/ieee1275/ieee1275.h,v
> retrieving revision 1.8
> diff -u -p -r1.8 ieee1275.h
> --- include/grub/powerpc/ieee1275/ieee1275.h 15 Oct 2004 02:29:11
> -0000 1.8
> +++ include/grub/powerpc/ieee1275/ieee1275.h 15 Oct 2004 22:19:54 -0000
> @@ -39,6 +39,27 @@ struct grub_ieee1275_mem_region
> unsigned int size;
> };
>
> +extern intptr_t (*grub_ieee1275_entry_fn) (void *);
> +
> +#ifndef IEEE1275_CALL_ENTRY_FN
> +#define IEEE1275_CALL_ENTRY_FN(args) (*grub_ieee1275_entry_fn) (args)
> +#endif
> +
> +/* All backcalls to the firmware is done by calling an entry function
> + which was passed to us from the bootloader. When doing the
> backcall,
> + a structure is passed which specifies what the firmware should do.
> + NAME is the requested service. NR_INS and NR_OUTS is the number of
> + passed arguments and the expected number of return values, resp. */
> +struct grub_ieee1275_common_hdr
> +{
> + char *name;
> + int nr_ins;
> + int nr_outs;
> +};
> +
> +#define INIT_IEEE1275_COMMON(p, xname, xins, xouts) \
> + (p)->name = xname; (p)->nr_ins = xins; (p)->nr_outs = xouts
> +
> /* FIXME jrydberg: is this correct cell types? */
> typedef intptr_t grub_ieee1275_ihandle_t;
> typedef intptr_t grub_ieee1275_phandle_t;
> @@ -103,6 +124,7 @@ grub_err_t EXPORT_FUNC(grub_devalias_ite
> (int (*hook) (struct grub_ieee1275_devalias *alias));
> grub_err_t EXPORT_FUNC(grub_children_iterate) (char *devpath,
> int (*hook) (struct grub_ieee1275_devalias *alias));
> +int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
>
> void EXPORT_FUNC(abort) (void);
>
> Index: kern/powerpc/ieee1275/openfw.c
> ===================================================================
> RCS file: /cvsroot/grub/grub2/kern/powerpc/ieee1275/openfw.c,v
> retrieving revision 1.3
> diff -u -p -r1.3 openfw.c
> --- kern/powerpc/ieee1275/openfw.c 13 Oct 2004 23:43:44 -0000 1.3
> +++ kern/powerpc/ieee1275/openfw.c 15 Oct 2004 22:19:55 -0000
> @@ -137,3 +137,57 @@ grub_devalias_iterate (int (*hook) (stru
>
> return 0;
> }
> +
> +/* Call the "map" method of /chosen/mmu. */
> +int
> +grub_map (grub_addr_t phys, grub_addr_t virt, grub_uint32_t size,
> + grub_uint8_t mode)
> +{
> + struct map_args {
> + struct grub_ieee1275_common_hdr common;
> + char *method;
> + grub_ieee1275_ihandle_t ihandle;
> + grub_uint32_t mode;
> + grub_uint32_t size;
> + grub_uint32_t virt;
> + grub_uint32_t phys;
> + int catch_result;
> + } args;
> + grub_ieee1275_ihandle_t mmu;
> + grub_ieee1275_ihandle_t chosen;
> + int len;
> +
> + grub_ieee1275_finddevice ("/chosen", &chosen);
> + if (chosen == 0)
> + return -1;
> +
> + grub_ieee1275_get_property (chosen, "mmu", &mmu, sizeof mmu, &len);
> + if (len != sizeof mmu)
> + return -1;
> +
> + INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1);
> + args.method = "map";
> + args.ihandle = mmu;
> + args.phys = phys;
> + args.virt = virt;
> + args.size = size;
> + args.mode = mode; /* Format is WIMG0PP. */
> +
> + if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
> + return -1;
> +
> + return args.catch_result;
> +}
> +
> +int
> +grub_claimmap (grub_addr_t addr, grub_size_t size)
> +{
> + if (grub_ieee1275_claim (addr, size, 0, 0))
> + return -1;
> + if (grub_map (addr, addr, size, 0x00))
> + {
> + grub_ieee1275_release (addr, size);
> + return -1;
> + }
> + return 0;
> +}
> Index: loader/powerpc/ieee1275/linux.c
> ===================================================================
> RCS file: /cvsroot/grub/grub2/loader/powerpc/ieee1275/linux.c,v
> retrieving revision 1.3
> diff -u -p -r1.3 linux.c
> --- loader/powerpc/ieee1275/linux.c 3 Oct 2004 09:19:10 -0000 1.3
> +++ loader/powerpc/ieee1275/linux.c 15 Oct 2004 22:19:56 -0000
> @@ -188,12 +188,13 @@ grub_load_linux (int argc, char *argv[])
> /* Reserve memory for the kernel. */
> linux_size += 0x100000;
>
> - if (grub_ieee1275_claim (entry, linux_size, 0, &linux_addr) == -1)
> + if (grub_claimmap (entry, linux_size) == -1)
> {
> grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not claim memory");
> goto fail;
> }
> -
> + linux_addr = entry;
> +
> /* Load every loadable segment in memory. */
> for (i = 0; i < ehdr.e_phnum; i++)
> {
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2004-10-20 12:07 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-10-15 22:35 [ppc patch] remove BAT mappings Hollis Blanchard
2004-10-20 1:30 ` Hollis Blanchard
2004-10-20 8:57 ` Marco Gerards
2004-10-20 12:02 ` Johan Rydberg
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.