this the hibats mapping patch. I have to manually edit out things that
are only relevant on our board.

--- 2.6.7/linux/arch/ppc/mm/pgtable.c Fri, 18 Jun 2004 13:35:07 -0400 linhd 
(k26/O/c/1_pgtable.c 1.1 644)
+++ local-2.6.7/arch/ppc/mm/pgtable.c Thu, 24 Jun 2004 15:24:06 -0400 linhd 
(k26/O/c/1_pgtable.c 1.3 644)
@@ -34,9 +34,11 @@

 #include "mmu_decl.h"

+extern int bat_map_io_succeed(unsigned long virt, phys_addr_t phys,
+                              unsigned int  size, int flags);
+
 unsigned long ioremap_base;
 unsigned long ioremap_bot;
-int io_bat_index;

 #if defined(CONFIG_6xx) || defined(CONFIG_POWER3)
 #define HAVE_BATS      1
@@ -297,9 +299,6 @@
        }
 }

-/* is x a power of 2? */
-#define is_power_of_2(x)       ((x) != 0 && (((x) & ((x) - 1)) == 0))
-
 /*
  * Set up a mapping for a block of I/O.
  * virt, phys, size must all be page-aligned.
@@ -317,13 +316,9 @@
        /*
         * Use a BAT for this if possible...
         */
-       if (io_bat_index < 2 && is_power_of_2(size)
-           && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
-               setbat(io_bat_index, virt, phys, size, flags);
-               ++io_bat_index;
+        if (bat_map_io_succeed(virt, phys, size, flags))
                return;
-       }
 #endif /* HAVE_BATS */

        /* No BATs available, put it in the page tables. */
--- 2.6.7/linux/arch/ppc/mm/ppc_mmu.c Fri, 18 Jun 2004 13:35:07 -0400 linhd 
(k26/O/c/2_ppc_mmu.c 1.1 644)
+++ local-2.6.7/arch/ppc/mm/ppc_mmu.c Tue, 29 Jun 2004 11:11:15 -0400 linhd 
(k26/O/c/2_ppc_mmu.c 1.3 644)
@@ -40,6 +40,17 @@
 unsigned long Hash_size, Hash_mask;
 unsigned long _SDR1;

+
+#define PPC32_MAX_BAT_PAIRS 8   /* maximum 8  dbats and 8  ibats */
+
+unsigned cpu_num_bat_pairs = 4; /* the actual number of bat pairs for
+                                 * this CPU. default to 4 for most
+                                 * ppc32  */
+
+unsigned cpu_num_ram_bats;
+
+int io_bat_index;               /* the 1st bat for I/O mapping */
+
 union ubat {                   /* BAT register values to be loaded */
        BAT     bat;
 #ifdef CONFIG_PPC64BRIDGE
@@ -47,13 +58,14 @@
 #else
        u32     word[2];
 #endif
-} BATS[4][2];                  /* 4 pairs of IBAT, DBAT */
+} BATS[PPC32_MAX_BAT_PAIRS][2];                        /* 8 pairs of IBAT, 
DBAT */

 struct batrange {              /* stores address ranges mapped by BATs */
        unsigned long start;
        unsigned long limit;
        unsigned long phys;
-} bat_addrs[4];
+} bat_addrs[PPC32_MAX_BAT_PAIRS];
+

 /*
  * Return PA for this VA if it is mapped by a BAT, or 0
@@ -61,7 +73,7 @@
 unsigned long v_mapped_by_bats(unsigned long va)
 {
        int b;
-       for (b = 0; b < 4; ++b)
+       for (b = 0; b < cpu_num_bat_pairs; ++b)
                if (va >= bat_addrs[b].start && va < bat_addrs[b].limit)
                        return bat_addrs[b].phys + (va - bat_addrs[b].start);
        return 0;
@@ -73,7 +85,7 @@
 unsigned long p_mapped_by_bats(unsigned long pa)
 {
        int b;
-       for (b = 0; b < 4; ++b)
+       for (b = 0; b < cpu_num_bat_pairs; ++b)
                if (pa >= bat_addrs[b].phys
                    && pa < (bat_addrs[b].limit-bat_addrs[b].start)
                              +bat_addrs[b].phys)
@@ -81,14 +93,35 @@
        return 0;
 }

+
+int
+bat_map_io_succeed(unsigned long virt, phys_addr_t phys,
+                   unsigned int size, int flags)
+{
+/* is x a power of 2? */
+#define is_power_of_2(x)       ((x) != 0 && (((x) & ((x) - 1)) == 0))
+
+#if defined(CONFIG_6xx) || defined(CONFIG_POWER3)
+        if (io_bat_index < cpu_num_bat_pairs && is_power_of_2(size)
+                 && (virt & (size - 1)) == 0 && (phys & (size - 1)) == 0) {
+               setbat(io_bat_index, virt, phys, size, flags);
+               ++io_bat_index;
+                return 1;
+       }
+#endif
+        return 0;
+}
+
+
 unsigned long __init mmu_mapin_ram(void)
 {
 #ifdef CONFIG_POWER4
        return 0;
 #else
-       unsigned long tot, bl, done;
+       unsigned long tot, bl, done = 0;
        unsigned long max_size = (256<<20);
        unsigned long align;
+        unsigned i;

        if (__map_without_bats)
                return 0;
@@ -103,24 +136,29 @@
        if (align && align < max_size)
                max_size = align;

+        cpu_num_ram_bats = cpu_num_bat_pairs / 2;
+/*         if (cpu_num_bat_pairs > 4) */
+/*                 cpu_num_ram_bats++; */
+
+        /*
+         * cpu_num_ram_bats bats registers from bat0 will be used to
+         * map ram. the rest will be used to map I/O
+         */
+
        tot = total_lowmem;
-       for (bl = 128<<10; bl < max_size; bl <<= 1) {
-               if (bl * 2 > tot)
-                       break;
-       }

-       setbat(2, KERNELBASE, PPC_MEMSTART, bl, _PAGE_RAM);
-       done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1;
-       if ((done < tot) && !bat_addrs[3].limit) {
-               /* use BAT3 to cover a bit more */
-               tot -= done;
-               for (bl = 128<<10; bl < max_size; bl <<= 1)
-                       if (bl * 2 > tot)
-                               break;
-               setbat(3, KERNELBASE+done, PPC_MEMSTART+done, bl, _PAGE_RAM);
-               done = (unsigned long)bat_addrs[3].limit - KERNELBASE + 1;
+        for (i = 0, bl = 1UL << __ilog2(tot - done);
+
+             i < cpu_num_ram_bats && done < tot && bat_addrs[i].limit == 0;
+
+             i++, bl = 1UL << __ilog2(tot - done))
+        {
+                setbat(i, KERNELBASE+done, PPC_MEMSTART+done, bl, _PAGE_RAM);
+                done = (unsigned long) bat_addrs[i].limit - KERNELBASE + 1;
        }

+        io_bat_index = i;       /* set the 1st bat used for I/O mapping */
+
        return done;
 #endif
 }
@@ -203,7 +241,16 @@
                return;
        }

+        if (cur_cpu_spec[0]->cpu_features & CPU_FTR_HAS_HIGH_BATS)
+        {
+                cpu_num_bat_pairs = 8;
+                if ( ppc_md.progress ) ppc_md.progress("cpu has hi bat 
registers", 8);
+        }
+
+        if ( ppc_md.progress ) ppc_md.progress("num bat pairs:", 
cpu_num_bat_pairs);
+
+
        if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105);

 #ifdef CONFIG_PPC64BRIDGE
--- 2.6.7/linux/arch/ppc/kernel/head.S Fri, 18 Jun 2004 13:35:07 -0400 linhd 
(k26/P/c/20_head.S 1.1 644)
+++ local-2.6.7/arch/ppc/kernel/head.S Thu, 24 Jun 2004 15:25:46 -0400 linhd 
(k26/P/c/20_head.S 1.2 644)
@@ -1328,7 +1328,13 @@
        LOAD_BAT(1,r3,r4,r5)
        LOAD_BAT(2,r3,r4,r5)
        LOAD_BAT(3,r3,r4,r5)
+BEGIN_FTR_SECTION
+       LOAD_BAT(4,r3,r4,r5)
+       LOAD_BAT(5,r3,r4,r5)
+       LOAD_BAT(6,r3,r4,r5)
+       LOAD_BAT(7,r3,r4,r5)
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
 #endif /* CONFIG_POWER4 */
        blr

--- 2.6.7/linux/arch/ppc/kernel/cpu_setup_6xx.S Fri, 18 Jun 2004 13:35:07 -0400 
linhd (k26/P/c/32_cpu_setup_ 1.1 644)
+++ local-2.6.7/arch/ppc/kernel/cpu_setup_6xx.S Thu, 24 Jun 2004 09:00:55 -0400 
linhd (k26/P/c/32_cpu_setup_ 1.2 644)
@@ -223,6 +223,10 @@
        oris    r11,r11,HID0_DPM at h   /* enable dynamic power mgmt */
 END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)

+BEGIN_FTR_SECTION
+        oris     r11,r11,HID0_HIGH_BAT at h
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
+
        /* All of the bits we have to clear....
         */
        li      r3,HID0_SPD | HID0_NOPDST | HID0_NOPTI

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/



Reply via email to