From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.33) id 1CIasW-0000VR-Hw for mharc-grub-devel@gnu.org; Fri, 15 Oct 2004 18:48:52 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1CIasU-0000V8-OE for grub-devel@gnu.org; Fri, 15 Oct 2004 18:48:50 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1CIasU-0000Uu-5U for grub-devel@gnu.org; Fri, 15 Oct 2004 18:48:50 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1CIasU-0000Ur-07 for grub-devel@gnu.org; Fri, 15 Oct 2004 18:48:50 -0400 Received: from [207.217.121.183] (helo=pop-a065c05.pas.sa.earthlink.net) by monty-python.gnu.org with esmtp (Exim 4.34) id 1CIalF-0008Bg-Rc for grub-devel@gnu.org; Fri, 15 Oct 2004 18:41:22 -0400 Received: from user-0vvde2s.cable.mindspring.com ([63.246.184.92] helo=miracle) by pop-a065c05.pas.sa.earthlink.net with esmtp (Exim 3.33 #1) id 1CIalE-0004Cv-00 for grub-devel@gnu.org; Fri, 15 Oct 2004 15:41:20 -0700 Received: from hollis by miracle with local (Exim 3.36 #1 (Debian)) id 1CIaf7-00026u-00 for ; Fri, 15 Oct 2004 17:35:01 -0500 Date: Fri, 15 Oct 2004 17:35:00 -0500 To: grub-devel@gnu.org Message-ID: <20041015223500.GA8099@miracle> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.6+20040722i From: Hollis Blanchard Subject: [ppc patch] remove BAT mappings X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Oct 2004 22:48:50 -0000 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 * 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++) {