summaryrefslogtreecommitdiffstats
path: root/arch/ppc/mm
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-06-19 22:45:37 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-06-19 22:45:37 +0000
commit6d403070f28cd44860fdb3a53be5da0275c65cf4 (patch)
tree0d0e7fe7b5fb7568d19e11d7d862b77a866ce081 /arch/ppc/mm
parentecf1bf5f6c2e668d03b0a9fb026db7aa41e292e1 (diff)
Merge with 2.4.0-test1-ac21 + pile of MIPS cleanups to make merging
possible. Chainsawed RM200 kernel to compile again. Jazz machine status unknown.
Diffstat (limited to 'arch/ppc/mm')
-rw-r--r--arch/ppc/mm/fault.c10
-rw-r--r--arch/ppc/mm/init.c192
-rw-r--r--arch/ppc/mm/mem_pieces.c48
-rw-r--r--arch/ppc/mm/mem_pieces.h13
4 files changed, 131 insertions, 132 deletions
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 7a899252f..0b551c803 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -238,11 +238,17 @@ bad_page_fault(struct pt_regs *regs, unsigned long address)
/* The pgtable.h claims some functions generically exist, but I
* can't find them......
*/
-pte_t *find_pte(struct mm_struct *mm, unsigned long address)
+pte_t *va_to_pte(unsigned long address)
{
pgd_t *dir;
pmd_t *pmd;
pte_t *pte;
+ struct mm_struct *mm;
+
+ if (address < TASK_SIZE)
+ mm = current->mm;
+ else
+ mm = &init_mm;
dir = pgd_offset(mm, address & PAGE_MASK);
if (dir) {
@@ -267,7 +273,7 @@ unsigned long va_to_phys(unsigned long address)
{
pte_t *pte;
- pte = find_pte(current->mm, address);
+ pte = va_to_pte(address);
if (pte)
return(((unsigned long)(pte_val(*pte)) & PAGE_MASK) | (address & ~(PAGE_MASK-1)));
return (0);
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index fc3acdd5c..0cfb5916c 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -94,6 +94,7 @@ unsigned long avail_start;
extern int num_memory;
extern struct mem_info memory[];
extern boot_infos_t *boot_infos;
+extern unsigned int rtas_data, rtas_size;
#ifndef CONFIG_SMP
struct pgtable_cache_struct quicklists;
#endif
@@ -116,21 +117,26 @@ unsigned long *m8260_find_end_of_memory(void);
#endif /* CONFIG_8260 */
static void mapin_ram(void);
void map_page(unsigned long va, unsigned long pa, int flags);
+void set_phys_avail(struct mem_pieces *mp);
extern void die_if_kernel(char *,struct pt_regs *,long);
-struct mem_pieces phys_mem;
-
+extern char _start[], _end[];
+extern char _stext[], etext[];
extern struct task_struct *current_set[NR_CPUS];
-PTE *Hash, *Hash_end;
-unsigned long Hash_size, Hash_mask;
+struct mem_pieces phys_mem;
+char *klimit = _end;
+struct mem_pieces phys_avail;
+
+PTE *Hash=0, *Hash_end;
+unsigned long Hash_size=0, Hash_mask;
#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
-unsigned long _SDR1;
+unsigned long _SDR1=0;
static void hash_init(void);
union ubat { /* BAT register values to be loaded */
BAT bat;
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC64BRIDGE
u64 word[2];
#else
u32 word[2];
@@ -479,7 +485,8 @@ map_page(unsigned long va, unsigned long pa, int flags)
if (pmd_none(oldpd) && mem_init_done)
set_pgdir(va, *(pgd_t *)pd);
set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags)));
- flush_hash_page(0, va);
+ if (mem_init_done)
+ flush_hash_page(0, va);
}
#ifndef CONFIG_8xx
@@ -503,11 +510,16 @@ map_page(unsigned long va, unsigned long pa, int flags)
void
local_flush_tlb_all(void)
{
+#ifdef CONFIG_PPC64BRIDGE
+ /* XXX this assumes that the vmalloc arena starts no lower than
+ * 0xd0000000 on 64-bit machines. */
+ flush_hash_segments(0xd, 0xffffff);
+#else
__clear_user(Hash, Hash_size);
- _tlbia();
#ifdef CONFIG_SMP
smp_send_tlb_invalidate(0);
-#endif
+#endif /* CONFIG_SMP */
+#endif /* CONFIG_PPC64BRIDGE */
}
/*
@@ -591,7 +603,10 @@ mmu_context_overflow(void)
atomic_set(&next_mmu_context, 0);
/* make sure current always has a context */
current->mm->context = MUNGE_CONTEXT(atomic_inc_return(&next_mmu_context));
- set_context(current->mm->context);
+ /* The PGD is only a placeholder. It is only used on
+ * 8xx processors.
+ */
+ set_context(current->mm->context, current->mm->pgd);
}
#endif /* CONFIG_8xx */
@@ -690,7 +705,7 @@ static void __init mapin_ram(void)
int i;
unsigned long v, p, s, f;
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_POWER4)
if (!__map_without_bats) {
unsigned long tot, mem_base, bl, done;
unsigned long max_size = (256<<20);
@@ -725,7 +740,7 @@ static void __init mapin_ram(void)
RAM_PAGE);
}
}
-#endif /* !CONFIG_4xx && !CONFIG_8xx */
+#endif /* !CONFIG_4xx && !CONFIG_8xx && !CONFIG_POWER4 */
for (i = 0; i < phys_mem.n_regions; ++i) {
v = (ulong)__va(phys_mem.regions[i].address);
@@ -940,9 +955,7 @@ void __init MMU_init(void)
if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300);
hash_init();
-#ifdef CONFIG_PPC64
- _SDR1 = __pa(Hash) | (ffz(~Hash_size) - 7)-11;
-#else
+#ifndef CONFIG_PPC64BRIDGE
_SDR1 = __pa(Hash) | (Hash_mask >> 10);
#endif
@@ -952,6 +965,11 @@ void __init MMU_init(void)
/* Map in all of RAM starting at KERNELBASE */
mapin_ram();
+#ifdef CONFIG_POWER4
+ ioremap_base = ioremap_bot = 0xfffff000;
+ isa_io_base = (unsigned long) ioremap(0xffd00000, 0x200000) + 0x100000;
+
+#else /* CONFIG_POWER4 */
/*
* Setup the bat mappings we're going to load that cover
* the io areas. RAM was mapped by mapin_ram().
@@ -966,26 +984,15 @@ void __init MMU_init(void)
break;
case _MACH_chrp:
setbat(0, 0xf8000000, 0xf8000000, 0x08000000, IO_PAGE);
-#ifdef CONFIG_PPC64
- /* temporary hack to get working until page tables are stable -- Cort*/
-/* setbat(1, 0x80000000, 0xc0000000, 0x10000000, IO_PAGE);*/
- setbat(3, 0xd0000000, 0xd0000000, 0x10000000, IO_PAGE);
+#ifdef CONFIG_PPC64BRIDGE
+ setbat(1, 0x80000000, 0xc0000000, 0x10000000, IO_PAGE);
#else
setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
setbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
-#endif
+#endif
break;
case _MACH_Pmac:
-#if 0
- {
- unsigned long base = 0xf3000000;
- struct device_node *macio = find_devices("mac-io");
- if (macio && macio->n_addrs)
- base = macio->addrs[0].address;
- setbat(0, base, base, 0x100000, IO_PAGE);
- }
-#endif
- ioremap_base = 0xf0000000;
+ ioremap_base = 0xf8000000;
break;
case _MACH_apus:
/* Map PPC exception vectors. */
@@ -1009,6 +1016,7 @@ void __init MMU_init(void)
break;
}
ioremap_bot = ioremap_base;
+#endif /* CONFIG_POWER4 */
#else /* CONFIG_8xx */
end_of_DRAM = m8xx_find_end_of_memory();
@@ -1080,6 +1088,7 @@ void __init do_init_bootmem(void)
/* remove the bootmem bitmap from the available memory */
mem_pieces_remove(&phys_avail, start, boot_mapsize, 1);
+
/* add everything in phys_avail into the bootmem map */
for (i = 0; i < phys_avail.n_regions; ++i)
free_bootmem(phys_avail.regions[i].address,
@@ -1159,9 +1168,6 @@ void __init mem_init(void)
int codepages = 0;
int datapages = 0;
int initpages = 0;
-#if defined(CONFIG_ALL_PPC)
- extern unsigned int rtas_data, rtas_size;
-#endif /* defined(CONFIG_ALL_PPC) */
max_mapnr = max_low_pfn;
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
num_physpages = max_mapnr; /* RAM is assumed contiguous */
@@ -1223,13 +1229,7 @@ void __init mem_init(void)
unsigned long __init *pmac_find_end_of_memory(void)
{
unsigned long a, total;
- unsigned long ram_limit = 0xf0000000 - KERNELBASE;
- /* allow 0x08000000 for IO space */
- if ( _machine & (_MACH_prep|_MACH_Pmac) )
- ram_limit = 0xd8000000 - KERNELBASE;
-#ifdef CONFIG_PPC64
- ram_limit = 64<<20;
-#endif
+ unsigned long ram_limit = 0xe0000000 - KERNELBASE;
memory_node = find_devices("memory");
if (memory_node == NULL) {
@@ -1422,27 +1422,42 @@ unsigned long __init *apus_find_end_of_memory(void)
*/
static void __init hash_init(void)
{
- int Hash_bits;
- unsigned long h, ramsize;
+ int Hash_bits, mb, mb2;
+ unsigned int hmask, ramsize, h;
extern unsigned int hash_page_patch_A[], hash_page_patch_B[],
hash_page_patch_C[], hash_page[];
+ ramsize = (ulong)end_of_DRAM - KERNELBASE;
+#ifdef CONFIG_PPC64BRIDGE
+ /* The hash table has already been allocated and initialized
+ in prom.c */
+ Hash_mask = (Hash_size >> 7) - 1;
+ hmask = Hash_mask >> 9;
+ Hash_bits = __ilog2(Hash_size) - 7;
+ mb = 25 - Hash_bits;
+ if (Hash_bits > 16)
+ Hash_bits = 16;
+ mb2 = 25 - Hash_bits;
+
+#else /* CONFIG_PPC64BRIDGE */
+
if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105);
/*
* Allow 64k of hash table for every 16MB of memory,
* up to a maximum of 2MB.
*/
- ramsize = (ulong)end_of_DRAM - KERNELBASE;
- for (h = 64<<10; h < ramsize / 256 && h < 2<<20; h *= 2)
+ for (h = 64<<10; h < ramsize / 256 && h < (2<<20); h *= 2)
;
Hash_size = h;
-#ifdef CONFIG_PPC64
- Hash_mask = (h >> 7) - 1;
-#else
Hash_mask = (h >> 6) - 1;
-#endif
-
+ hmask = Hash_mask >> 10;
+ Hash_bits = __ilog2(h) - 6;
+ mb = 26 - Hash_bits;
+ if (Hash_bits > 16)
+ Hash_bits = 16;
+ mb2 = 26 - Hash_bits;
+
/* shrink the htab since we don't use it on 603's -- Cort */
switch (_get_PVR()>>16) {
case 3: /* 603 */
@@ -1459,50 +1474,36 @@ static void __init hash_init(void)
if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
/* Find some memory for the hash table. */
- if ( Hash_size )
+ if ( Hash_size ) {
Hash = mem_pieces_find(Hash_size, Hash_size);
- else
+ /*__clear_user(Hash, Hash_size);*/
+ } else
Hash = 0;
+#endif /* CONFIG_PPC64BRIDGE */
- printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n",
+ printk("Total memory = %dMB; using %ldkB for hash table (at %p)\n",
ramsize >> 20, Hash_size >> 10, Hash);
if ( Hash_size )
{
if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345);
Hash_end = (PTE *) ((unsigned long)Hash + Hash_size);
- /*__clear_user(Hash, Hash_size);*/
/*
* Patch up the instructions in head.S:hash_page
*/
-#ifdef CONFIG_PPC64
- Hash_bits = ffz(~Hash_size) - 7;
-#else
- Hash_bits = ffz(~Hash_size) - 6;
-#endif
hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff)
| (__pa(Hash) >> 16);
hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0)
- | ((26 - Hash_bits) << 6);
- if (Hash_bits > 16)
- Hash_bits = 16;
+ | (mb << 6);
hash_page_patch_A[2] = (hash_page_patch_A[2] & ~0x7c0)
- | ((26 - Hash_bits) << 6);
+ | (mb2 << 6);
hash_page_patch_B[0] = (hash_page_patch_B[0] & ~0xffff)
-#ifdef CONFIG_PPC64
- | (Hash_mask >> 11);
-#else
- | (Hash_mask >> 10);
-#endif
+ | hmask;
hash_page_patch_C[0] = (hash_page_patch_C[0] & ~0xffff)
-#ifdef CONFIG_PPC64
- | (Hash_mask >> 11);
-#else
- | (Hash_mask >> 10);
-#endif
+ | hmask;
#if 0 /* see hash_page in head.S, note also patch_C ref below */
hash_page_patch_D[0] = (hash_page_patch_D[0] & ~0xffff)
- | (Hash_mask >> 10);
+ | hmask;
#endif
/*
* Ensure that the locations we've patched have been written
@@ -1579,3 +1580,48 @@ oak_find_end_of_memory(void)
return (ret);
}
#endif
+
+/*
+ * Set phys_avail to phys_mem less the kernel text/data/bss.
+ */
+void __init
+set_phys_avail(struct mem_pieces *mp)
+{
+ unsigned long kstart, ksize;
+
+ /*
+ * Initially, available phyiscal memory is equivalent to all
+ * physical memory.
+ */
+
+ phys_avail = *mp;
+
+ /*
+ * Map out the kernel text/data/bss from the available physical
+ * memory.
+ */
+
+ kstart = __pa(_stext); /* should be 0 */
+ ksize = PAGE_ALIGN(klimit - _stext);
+
+ mem_pieces_remove(&phys_avail, kstart, ksize, 0);
+ mem_pieces_remove(&phys_avail, 0, 0x4000, 0);
+
+#if defined(CONFIG_BLK_DEV_INITRD)
+ /* Remove the init RAM disk from the available memory. */
+ if (initrd_start) {
+ mem_pieces_remove(&phys_avail, __pa(initrd_start),
+ initrd_end - initrd_start, 1);
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+#ifdef CONFIG_ALL_PPC
+ /* remove the RTAS pages from the available memory */
+ if (rtas_data)
+ mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);
+#endif /* CONFIG_ALL_PPC */
+#ifdef CONFIG_PPC64BRIDGE
+ /* Remove the hash table from the available memory */
+ if (Hash)
+ mem_pieces_remove(&phys_avail, __pa(Hash), Hash_size, 1);
+#endif /* CONFIG_PPC64BRIDGE */
+}
diff --git a/arch/ppc/mm/mem_pieces.c b/arch/ppc/mm/mem_pieces.c
index 309a526f5..a329cca7a 100644
--- a/arch/ppc/mm/mem_pieces.c
+++ b/arch/ppc/mm/mem_pieces.c
@@ -18,18 +18,11 @@
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/blk.h>
-
-#include <asm/page.h>
-#include <asm/prom.h>
+#include <linux/init.h>
#include "mem_pieces.h"
-extern char _start[], _end[];
-extern char _stext[], etext[];
-
-char *klimit = _end;
-
-struct mem_pieces phys_avail;
+extern struct mem_pieces phys_avail;
static void mem_pieces_print(struct mem_pieces *);
@@ -142,7 +135,7 @@ mem_pieces_append(struct mem_pieces *mp, unsigned int start, unsigned int size)
rp->address = start;
rp->size = size;
}
-#endif
+#endif /* CONFIG_APUS || CONFIG_ALL_PPC */
void __init
mem_pieces_sort(struct mem_pieces *mp)
@@ -185,38 +178,3 @@ mem_pieces_coalesce(struct mem_pieces *mp)
}
mp->n_regions = d;
}
-
-/*
- * Set phys_avail to phys_mem less the kernel text/data/bss.
- */
-void __init
-set_phys_avail(struct mem_pieces *mp)
-{
- unsigned long kstart, ksize;
-
- /*
- * Initially, available phyiscal memory is equivalent to all
- * physical memory.
- */
-
- phys_avail = *mp;
-
- /*
- * Map out the kernel text/data/bss from the available physical
- * memory.
- */
-
- kstart = __pa(_stext); /* should be 0 */
- ksize = PAGE_ALIGN(klimit - _stext);
-
- mem_pieces_remove(&phys_avail, kstart, ksize, 0);
- mem_pieces_remove(&phys_avail, 0, 0x4000, 0);
-
-#if defined(CONFIG_BLK_DEV_INITRD)
- /* Remove the init RAM disk from the available memory. */
- if (initrd_start) {
- mem_pieces_remove(&phys_avail, __pa(initrd_start),
- initrd_end - initrd_start, 1);
- }
-#endif /* CONFIG_BLK_DEV_INITRD */
-}
diff --git a/arch/ppc/mm/mem_pieces.h b/arch/ppc/mm/mem_pieces.h
index 6dbe045da..bc8e2861c 100644
--- a/arch/ppc/mm/mem_pieces.h
+++ b/arch/ppc/mm/mem_pieces.h
@@ -17,8 +17,7 @@
#ifndef __MEM_PIECES_H__
#define __MEM_PIECES_H__
-#include <linux/init.h>
-
+#include <asm/prom.h>
#ifdef __cplusplus
extern "C" {
@@ -34,13 +33,6 @@ struct mem_pieces {
struct reg_property regions[MEM_PIECES_MAX];
};
-
-/* Global Variables */
-
-extern char *klimit;
-extern struct mem_pieces phys_avail;
-
-
/* Function Prototypes */
extern void *mem_pieces_find(unsigned int size, unsigned int align);
@@ -51,9 +43,6 @@ extern void mem_pieces_append(struct mem_pieces *mp, unsigned int start,
extern void mem_pieces_coalesce(struct mem_pieces *mp);
extern void mem_pieces_sort(struct mem_pieces *mp);
-extern void set_phys_avail(struct mem_pieces *mp);
-
-
#ifdef __cplusplus
}
#endif