All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hollis Blanchard <hollis@penguinppc.org>
To: grub-devel@gnu.org
Subject: [ppc patch] remove BAT mappings
Date: Fri, 15 Oct 2004 17:35:00 -0500	[thread overview]
Message-ID: <20041015223500.GA8099@miracle> (raw)

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++)
     {



             reply	other threads:[~2004-10-15 22:48 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-10-15 22:35 Hollis Blanchard [this message]
2004-10-20  1:30 ` [ppc patch] remove BAT mappings Hollis Blanchard
2004-10-20  8:57   ` Marco Gerards
2004-10-20 12:02     ` Johan Rydberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20041015223500.GA8099@miracle \
    --to=hollis@penguinppc.org \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.