powerpc/44x: Support 16K/64K base page sizes on 44x
[safe/jmp/linux-2.6] / arch / powerpc / mm / ppc_mmu_32.c
index 2ed43a4..45d9253 100644 (file)
@@ -11,7 +11,6 @@
  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
  *    Copyright (C) 1996 Paul Mackerras
- *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  *
  *  Derived from "arch/i386/mm/init.c"
  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  *
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/highmem.h>
+#include <linux/lmb.h>
 
 #include <asm/prom.h>
 #include <asm/mmu.h>
 #include <asm/machdep.h>
-#include <asm/lmb.h>
 
 #include "mmu_decl.h"
 
-PTE *Hash, *Hash_end;
+struct hash_pte *Hash, *Hash_end;
 unsigned long Hash_size, Hash_mask;
 unsigned long _SDR1;
 
-union ubat {                   /* BAT register values to be loaded */
-       BAT     bat;
-       u32     word[2];
-} BATS[8][2];                  /* 8 pairs of IBAT, DBAT */
+struct ppc_bat BATS[8][2];     /* 8 pairs of IBAT, DBAT */
 
 struct batrange {              /* stores address ranges mapped by BATs */
        unsigned long start;
        unsigned long limit;
-       unsigned long phys;
+       phys_addr_t phys;
 } bat_addrs[8];
 
 /*
  * Return PA for this VA if it is mapped by a BAT, or 0
  */
-unsigned long v_mapped_by_bats(unsigned long va)
+phys_addr_t v_mapped_by_bats(unsigned long va)
 {
        int b;
        for (b = 0; b < 4; ++b)
@@ -66,7 +61,7 @@ unsigned long v_mapped_by_bats(unsigned long va)
 /*
  * Return VA for a given PA or 0 if not mapped
  */
-unsigned long p_mapped_by_bats(unsigned long pa)
+unsigned long p_mapped_by_bats(phys_addr_t pa)
 {
        int b;
        for (b = 0; b < 4; ++b)
@@ -84,37 +79,32 @@ unsigned long __init mmu_mapin_ram(void)
 #else
        unsigned long tot, bl, done;
        unsigned long max_size = (256<<20);
-       unsigned long align;
 
-       if (__map_without_bats)
+       if (__map_without_bats) {
+               printk(KERN_DEBUG "RAM mapped without BATs\n");
                return 0;
+       }
 
        /* Set up BAT2 and if necessary BAT3 to cover RAM. */
 
        /* Make sure we don't map a block larger than the
           smallest alignment of the physical address. */
-       /* alignment of PPC_MEMSTART */
-       align = ~(PPC_MEMSTART-1) & PPC_MEMSTART;
-       /* set BAT block size to MIN(max_size, align) */
-       if (align && align < max_size)
-               max_size = align;
-
        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;
+       setbat(2, PAGE_OFFSET, 0, bl, _PAGE_RAM);
+       done = (unsigned long)bat_addrs[2].limit - PAGE_OFFSET + 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;
+               setbat(3, PAGE_OFFSET+done, done, bl, _PAGE_RAM);
+               done = (unsigned long)bat_addrs[3].limit - PAGE_OFFSET + 1;
        }
 
        return done;
@@ -126,12 +116,12 @@ unsigned long __init mmu_mapin_ram(void)
  * The parameters are not checked; in particular size must be a power
  * of 2 between 128k and 256M.
  */
-void __init setbat(int index, unsigned long virt, unsigned long phys,
+void __init setbat(int index, unsigned long virt, phys_addr_t phys,
                   unsigned int size, int flags)
 {
        unsigned int bl;
        int wimgxpp;
-       union ubat *bat = BATS[index];
+       struct ppc_bat *bat = BATS[index];
 
        if (((flags & _PAGE_NO_CACHE) == 0) &&
            cpu_has_feature(CPU_FTR_NEED_COHERENT))
@@ -144,15 +134,15 @@ void __init setbat(int index, unsigned long virt, unsigned long phys,
                wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
                                   | _PAGE_COHERENT | _PAGE_GUARDED);
                wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX;
-               bat[1].word[0] = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */
-               bat[1].word[1] = phys | wimgxpp;
+               bat[1].batu = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */
+               bat[1].batl = BAT_PHYS_ADDR(phys) | wimgxpp;
 #ifndef CONFIG_KGDB /* want user access for breakpoints */
                if (flags & _PAGE_USER)
 #endif
-                       bat[1].bat.batu.vp = 1;
+                       bat[1].batu |= 1;       /* Vp = 1 */
                if (flags & _PAGE_GUARDED) {
                        /* G bit must be zero in IBATs */
-                       bat[0].word[0] = bat[0].word[1] = 0;
+                       bat[0].batu = bat[0].batl = 0;
                } else {
                        /* make IBAT same as DBAT */
                        bat[0] = bat[1];
@@ -165,8 +155,8 @@ void __init setbat(int index, unsigned long virt, unsigned long phys,
                                   | _PAGE_COHERENT);
                wimgxpp |= (flags & _PAGE_RW)?
                        ((flags & _PAGE_USER)? PP_RWRW: PP_RWXX): PP_RXRX;
-               bat->word[0] = virt | wimgxpp | 4;      /* Ks=0, Ku=1 */
-               bat->word[1] = phys | bl | 0x40;        /* V=1 */
+               bat->batu = virt | wimgxpp | 4; /* Ks=0, Ku=1 */
+               bat->batl = phys | bl | 0x40;   /* V=1 */
        }
 
        bat_addrs[index].start = virt;
@@ -184,7 +174,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
 
        if (Hash == 0)
                return;
-       pmd = pmd_offset(pgd_offset(mm, ea), ea);
+       pmd = pmd_offset(pud_offset(pgd_offset(mm, ea), ea), ea);
        if (!pmd_none(*pmd))
                add_hash_page(mm->context.id, ea, pmd_val(*pmd));
 }
@@ -202,7 +192,7 @@ void __init MMU_init_hw(void)
        extern unsigned int hash_page[];
        extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[];
 
-       if (!cpu_has_feature(CPU_FTR_HPTE_TABLE)) {
+       if (!mmu_has_feature(MMU_FTR_HPTE_TABLE)) {
                /*
                 * Put a blr (procedure return) instruction at the
                 * start of hash_page, since we can still get DSI
@@ -240,14 +230,14 @@ void __init MMU_init_hw(void)
         */
        if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
        Hash = __va(lmb_alloc_base(Hash_size, Hash_size,
-                                  __initial_memory_limit));
+                                  __initial_memory_limit_addr));
        cacheable_memzero(Hash, Hash_size);
        _SDR1 = __pa(Hash) | SDR1_LOW_BITS;
 
-       Hash_end = (PTE *) ((unsigned long)Hash + Hash_size);
+       Hash_end = (struct hash_pte *) ((unsigned long)Hash + Hash_size);
 
-       printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n",
-              total_memory >> 20, Hash_size >> 10, Hash);
+       printk("Total memory = %lldMB; using %ldkB for hash table (at %p)\n",
+              (unsigned long long)(total_memory >> 20), Hash_size >> 10, Hash);
 
 
        /*