summary refs log tree commit diff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/include/asm/fixmap.h110
-rw-r--r--arch/sparc/include/asm/highmem.h3
-rw-r--r--arch/sparc/include/asm/leon.h1
-rw-r--r--arch/sparc/include/asm/mmu_context_32.h8
-rw-r--r--arch/sparc/include/asm/page_32.h3
-rw-r--r--arch/sparc/include/asm/pgalloc_32.h29
-rw-r--r--arch/sparc/include/asm/pgtable_32.h44
-rw-r--r--arch/sparc/include/asm/vaddrs.h22
-rw-r--r--arch/sparc/kernel/head_32.S2
-rw-r--r--arch/sparc/kernel/leon_kernel.c16
-rw-r--r--arch/sparc/kernel/process_32.c4
-rw-r--r--arch/sparc/kernel/setup_32.c1
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c17
-rw-r--r--arch/sparc/lib/NG2memcpy.S72
-rw-r--r--arch/sparc/lib/U1memcpy.S4
-rw-r--r--arch/sparc/lib/copy_page.S56
-rw-r--r--arch/sparc/mm/fault_32.c18
-rw-r--r--arch/sparc/mm/highmem.c42
-rw-r--r--arch/sparc/mm/init_32.c58
-rw-r--r--arch/sparc/mm/srmmu.c332
-rw-r--r--arch/sparc/prom/init_32.c7
-rw-r--r--arch/sparc/prom/init_64.c4
22 files changed, 331 insertions, 522 deletions
diff --git a/arch/sparc/include/asm/fixmap.h b/arch/sparc/include/asm/fixmap.h
deleted file mode 100644
index f18fc0755adf..000000000000
--- a/arch/sparc/include/asm/fixmap.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * fixmap.h: compile-time virtual memory allocation
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1998 Ingo Molnar
- *
- * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
- */
-
-#ifndef _ASM_FIXMAP_H
-#define _ASM_FIXMAP_H
-
-#include <linux/kernel.h>
-#include <asm/page.h>
-#ifdef CONFIG_HIGHMEM
-#include <linux/threads.h>
-#include <asm/kmap_types.h>
-#endif
-
-/*
- * Here we define all the compile-time 'special' virtual
- * addresses. The point is to have a constant address at
- * compile time, but to set the physical address only
- * in the boot process. We allocate these special  addresses
- * from the top of unused virtual memory (0xfd000000 - 1 page) backwards.
- * Also this lets us do fail-safe vmalloc(), we
- * can guarantee that these special addresses and
- * vmalloc()-ed addresses never overlap.
- *
- * these 'compile-time allocated' memory buffers are
- * fixed-size 4k pages. (or larger if used with an increment
- * highger than 1) use fixmap_set(idx,phys) to associate
- * physical memory with fixmap indices.
- *
- * TLB entries of such buffers will not be flushed across
- * task switches.
- */
-
-/*
- * on UP currently we will have no trace of the fixmap mechanism,
- * no page table allocations, etc. This might change in the
- * future, say framebuffers for the console driver(s) could be
- * fix-mapped?
- */
-enum fixed_addresses {
-	FIX_HOLE,
-#ifdef CONFIG_HIGHMEM
-	FIX_KMAP_BEGIN,
-	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
-#endif
-	__end_of_fixed_addresses
-};
-
-extern void __set_fixmap (enum fixed_addresses idx,
-					unsigned long phys, pgprot_t flags);
-
-#define set_fixmap(idx, phys) \
-		__set_fixmap(idx, phys, PAGE_KERNEL)
-/*
- * Some hardware wants to get fixmapped without caching.
- */
-#define set_fixmap_nocache(idx, phys) \
-		__set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
-/*
- * used by vmalloc.c.
- *
- * Leave one empty page between IO pages at 0xfd000000 and
- * the start of the fixmap.
- */
-#define FIXADDR_TOP	(0xfcfff000UL)
-#define FIXADDR_SIZE	((__end_of_fixed_addresses) << PAGE_SHIFT)
-#define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
-
-#define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
-#define __virt_to_fix(x)	((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
-
-extern void __this_fixmap_does_not_exist(void);
-
-/*
- * 'index to address' translation. If anyone tries to use the idx
- * directly without tranlation, we catch the bug with a NULL-deference
- * kernel oops. Illegal ranges of incoming indices are caught too.
- */
-static inline unsigned long fix_to_virt(const unsigned int idx)
-{
-	/*
-	 * this branch gets completely eliminated after inlining,
-	 * except when someone tries to use fixaddr indices in an
-	 * illegal way. (such as mixing up address types or using
-	 * out-of-range indices).
-	 *
-	 * If it doesn't get removed, the linker will complain
-	 * loudly with a reasonably clear error message..
-	 */
-	if (idx >= __end_of_fixed_addresses)
-		__this_fixmap_does_not_exist();
-
-        return __fix_to_virt(idx);
-}
-
-static inline unsigned long virt_to_fix(const unsigned long vaddr)
-{
-	BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
-	return __virt_to_fix(vaddr);
-}
-
-#endif
diff --git a/arch/sparc/include/asm/highmem.h b/arch/sparc/include/asm/highmem.h
index 3b6e00dd96e5..4f9e15c757e2 100644
--- a/arch/sparc/include/asm/highmem.h
+++ b/arch/sparc/include/asm/highmem.h
@@ -21,7 +21,6 @@
 #ifdef __KERNEL__
 
 #include <linux/interrupt.h>
-#include <asm/fixmap.h>
 #include <asm/vaddrs.h>
 #include <asm/kmap_types.h>
 #include <asm/pgtable.h>
@@ -29,7 +28,6 @@
 /* declarations for highmem.c */
 extern unsigned long highstart_pfn, highend_pfn;
 
-extern pte_t *kmap_pte;
 extern pgprot_t kmap_prot;
 extern pte_t *pkmap_page_table;
 
@@ -72,7 +70,6 @@ static inline void kunmap(struct page *page)
 
 extern void *kmap_atomic(struct page *page);
 extern void __kunmap_atomic(void *kvaddr);
-extern struct page *kmap_atomic_to_page(void *vaddr);
 
 #define flush_cache_kmaps()	flush_cache_all()
 
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h
index 3375c6293893..15a716934e4d 100644
--- a/arch/sparc/include/asm/leon.h
+++ b/arch/sparc/include/asm/leon.h
@@ -82,7 +82,6 @@ static inline unsigned long leon_load_reg(unsigned long paddr)
 #define LEON_BYPASS_LOAD_PA(x)      leon_load_reg((unsigned long)(x))
 #define LEON_BYPASS_STORE_PA(x, v)  leon_store_reg((unsigned long)(x), (unsigned long)(v))
 
-extern void leon_init(void);
 extern void leon_switch_mm(void);
 extern void leon_init_IRQ(void);
 
diff --git a/arch/sparc/include/asm/mmu_context_32.h b/arch/sparc/include/asm/mmu_context_32.h
index 01456c900720..2df2a9be8f6d 100644
--- a/arch/sparc/include/asm/mmu_context_32.h
+++ b/arch/sparc/include/asm/mmu_context_32.h
@@ -9,14 +9,12 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 {
 }
 
-/*
- * Initialize a new mmu context.  This is invoked when a new
+/* Initialize a new mmu context.  This is invoked when a new
  * address space instance (unique or shared) is instantiated.
  */
-#define init_new_context(tsk, mm) (((mm)->context = NO_CONTEXT), 0)
+int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
 
-/*
- * Destroy a dead context.  This occurs when mmput drops the
+/* Destroy a dead context.  This occurs when mmput drops the
  * mm_users count to zero, the mmaps have been released, and
  * all the page tables have been flushed.  Our job is to destroy
  * any remaining processor-specific state.
diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h
index fab78a308ebf..f82a1f36b655 100644
--- a/arch/sparc/include/asm/page_32.h
+++ b/arch/sparc/include/asm/page_32.h
@@ -107,8 +107,7 @@ typedef unsigned long iopgprot_t;
 
 typedef struct page *pgtable_t;
 
-extern unsigned long sparc_unmapped_base;
-#define TASK_UNMAPPED_BASE	sparc_unmapped_base
+#define TASK_UNMAPPED_BASE	0x50000000
 
 #else /* !(__ASSEMBLY__) */
 
diff --git a/arch/sparc/include/asm/pgalloc_32.h b/arch/sparc/include/asm/pgalloc_32.h
index e5b169b46d21..9b1c36de0f18 100644
--- a/arch/sparc/include/asm/pgalloc_32.h
+++ b/arch/sparc/include/asm/pgalloc_32.h
@@ -11,28 +11,15 @@
 
 struct page;
 
-extern struct pgtable_cache_struct {
-	unsigned long *pgd_cache;
-	unsigned long *pte_cache;
-	unsigned long pgtable_cache_sz;
-	unsigned long pgd_cache_sz;
-} pgt_quicklists;
-
-unsigned long srmmu_get_nocache(int size, int align);
-void srmmu_free_nocache(unsigned long vaddr, int size);
-
-#define pgd_quicklist           (pgt_quicklists.pgd_cache)
-#define pmd_quicklist           ((unsigned long *)0)
-#define pte_quicklist           (pgt_quicklists.pte_cache)
-#define pgtable_cache_size      (pgt_quicklists.pgtable_cache_sz)
-#define pgd_cache_size		(pgt_quicklists.pgd_cache_sz)
+void *srmmu_get_nocache(int size, int align);
+void srmmu_free_nocache(void *addr, int size);
 
 #define check_pgt_cache()	do { } while (0)
 
 pgd_t *get_pgd_fast(void);
 static inline void free_pgd_fast(pgd_t *pgd)
 {
-	srmmu_free_nocache((unsigned long)pgd, SRMMU_PGD_TABLE_SIZE);
+	srmmu_free_nocache(pgd, SRMMU_PGD_TABLE_SIZE);
 }
 
 #define pgd_free(mm, pgd)	free_pgd_fast(pgd)
@@ -50,13 +37,13 @@ static inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm,
 				   unsigned long address)
 {
-	return (pmd_t *)srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE,
-					  SRMMU_PMD_TABLE_SIZE);
+	return srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE,
+				 SRMMU_PMD_TABLE_SIZE);
 }
 
 static inline void free_pmd_fast(pmd_t * pmd)
 {
-	srmmu_free_nocache((unsigned long)pmd, SRMMU_PMD_TABLE_SIZE);
+	srmmu_free_nocache(pmd, SRMMU_PMD_TABLE_SIZE);
 }
 
 #define pmd_free(mm, pmd)		free_pmd_fast(pmd)
@@ -73,13 +60,13 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address);
 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
 					  unsigned long address)
 {
-	return (pte_t *)srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
+	return srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
 }
 
 
 static inline void free_pte_fast(pte_t *pte)
 {
-	srmmu_free_nocache((unsigned long)pte, PTE_SIZE);
+	srmmu_free_nocache(pte, PTE_SIZE);
 }
 
 #define pte_free_kernel(mm, pte)	free_pte_fast(pte)
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index cbbbed5cb3aa..6fc13483f702 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -52,8 +52,9 @@ extern unsigned long calc_highpages(void);
 #define PAGE_READONLY	SRMMU_PAGE_RDONLY
 #define PAGE_KERNEL	SRMMU_PAGE_KERNEL
 
-/* Top-level page directory */
-extern pgd_t swapper_pg_dir[1024];
+/* Top-level page directory - dummy used by init-mm.
+ * srmmu.c will assign the real one (which is dynamically sized) */
+#define swapper_pg_dir NULL
 
 extern void paging_init(void);
 
@@ -78,8 +79,6 @@ extern unsigned long ptr_in_current_pgd;
 #define __S110	PAGE_SHARED
 #define __S111	PAGE_SHARED
 
-extern int num_contexts;
-
 /* First physical page can be anywhere, the following is needed so that
  * va-->pa and vice versa conversions work properly without performance
  * hit for all __pa()/__va() operations.
@@ -88,18 +87,11 @@ extern unsigned long phys_base;
 extern unsigned long pfn_base;
 
 /*
- * BAD_PAGETABLE is used when we need a bogus page-table, while
- * BAD_PAGE is used for a bogus page.
- *
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
  */
-extern pte_t * __bad_pagetable(void);
-extern pte_t __bad_page(void);
 extern unsigned long empty_zero_page;
 
-#define BAD_PAGETABLE __bad_pagetable()
-#define BAD_PAGE __bad_page()
 #define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page))
 
 /*
@@ -398,36 +390,6 @@ static inline pte_t pgoff_to_pte(unsigned long pgoff)
  */
 #define PTE_FILE_MAX_BITS 24
 
-/*
- */
-struct ctx_list {
-	struct ctx_list *next;
-	struct ctx_list *prev;
-	unsigned int ctx_number;
-	struct mm_struct *ctx_mm;
-};
-
-extern struct ctx_list *ctx_list_pool;  /* Dynamically allocated */
-extern struct ctx_list ctx_free;        /* Head of free list */
-extern struct ctx_list ctx_used;        /* Head of used contexts list */
-
-#define NO_CONTEXT     -1
-
-static inline void remove_from_ctx_list(struct ctx_list *entry)
-{
-	entry->next->prev = entry->prev;
-	entry->prev->next = entry->next;
-}
-
-static inline void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry)
-{
-	entry->next = head;
-	(entry->prev = head->prev)->next = entry;
-	head->prev = entry;
-}
-#define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry)
-#define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry)
-
 static inline unsigned long
 __get_phys (unsigned long addr)
 {
diff --git a/arch/sparc/include/asm/vaddrs.h b/arch/sparc/include/asm/vaddrs.h
index da6535d88a72..c3dbcf902034 100644
--- a/arch/sparc/include/asm/vaddrs.h
+++ b/arch/sparc/include/asm/vaddrs.h
@@ -30,6 +30,28 @@
  */
 #define SRMMU_NOCACHE_ALCRATIO	64	/* 256 pages per 64MB of system RAM */
 
+#ifndef __ASSEMBLY__
+#include <asm/kmap_types.h>
+
+enum fixed_addresses {
+	FIX_HOLE,
+#ifdef CONFIG_HIGHMEM
+	FIX_KMAP_BEGIN,
+	FIX_KMAP_END = (KM_TYPE_NR * NR_CPUS),
+#endif
+	__end_of_fixed_addresses
+};
+#endif
+
+/* Leave one empty page between IO pages at 0xfd000000 and
+ * the top of the fixmap.
+ */
+#define FIXADDR_TOP		(0xfcfff000UL)
+#define FIXADDR_SIZE		((FIX_KMAP_END + 1) << PAGE_SHIFT)
+#define FIXADDR_START		(FIXADDR_TOP - FIXADDR_SIZE)
+
+#define __fix_to_virt(x)        (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+
 #define SUN4M_IOBASE_VADDR	0xfd000000 /* Base for mapping pages */
 #define IOBASE_VADDR		0xfe000000
 #define IOBASE_END		0xfe600000
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index afeb1d770303..3d92c0a8f6c4 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -58,8 +58,6 @@ sun4e_notsup:
 /* This was the only reasonable way I could think of to properly align
  * these page-table data structures.
  */
-	.globl swapper_pg_dir
-swapper_pg_dir:		.skip PAGE_SIZE
 	.globl empty_zero_page
 empty_zero_page:	.skip PAGE_SIZE
 
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index e34e2c40c060..f8b6eee40bde 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -486,17 +486,6 @@ void __init leon_trans_init(struct device_node *dp)
 	}
 }
 
-void __initdata (*prom_amba_init)(struct device_node *dp, struct device_node ***nextp) = 0;
-
-void __init leon_node_init(struct device_node *dp, struct device_node ***nextp)
-{
-	if (prom_amba_init &&
-	    strcmp(dp->type, "ambapp") == 0 &&
-	    strcmp(dp->name, "ambapp0") == 0) {
-		prom_amba_init(dp, nextp);
-	}
-}
-
 #ifdef CONFIG_SMP
 void leon_clear_profile_irq(int cpu)
 {
@@ -522,8 +511,3 @@ void __init leon_init_IRQ(void)
 	sparc_config.clear_clock_irq  = leon_clear_clock_irq;
 	sparc_config.load_profile_irq = leon_load_profile_irq;
 }
-
-void __init leon_init(void)
-{
-	of_pdt_build_more = &leon_node_init;
-}
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index cb36e82dcd5d..14006d8aca28 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -333,9 +333,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
 		put_psr(get_psr() | PSR_EF);
 		fpsave(&p->thread.float_regs[0], &p->thread.fsr,
 		       &p->thread.fpqueue[0], &p->thread.fpqdepth);
-#ifdef CONFIG_SMP
-		clear_thread_flag(TIF_USEDFPU);
-#endif
 	}
 
 	/*
@@ -413,6 +410,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
 #ifdef CONFIG_SMP
 	/* FPU must be disabled on SMP. */
 	childregs->psr &= ~PSR_EF;
+	clear_tsk_thread_flag(p, TIF_USEDFPU);
 #endif
 
 	/* Set the return value for the child. */
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index efe3e64bba38..38bf80a22f02 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -371,7 +371,6 @@ void __init setup_arch(char **cmdline_p)
 		(*(linux_dbvec->teach_debugger))();
 	}
 
-	init_mm.context = (unsigned long) NO_CONTEXT;
 	init_task.thread.kregs = &fake_swapper_regs;
 
 	/* Run-time patch instructions to match the cpu model */
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 275f74fd6f6a..c38e5aaae56f 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -66,23 +66,6 @@ static inline int invalid_64bit_range(unsigned long addr, unsigned long len)
 	return 0;
 }
 
-/* Does start,end straddle the VA-space hole?  */
-static inline int straddles_64bit_va_hole(unsigned long start, unsigned long end)
-{
-	unsigned long va_exclude_start, va_exclude_end;
-
-	va_exclude_start = VA_EXCLUDE_START;
-	va_exclude_end   = VA_EXCLUDE_END;
-
-	if (likely(start < va_exclude_start && end < va_exclude_start))
-		return 0;
-
-	if (likely(start >= va_exclude_end && end >= va_exclude_end))
-		return 0;
-
-	return 1;
-}
-
 /* These functions differ from the default implementations in
  * mm/mmap.c in two ways:
  *
diff --git a/arch/sparc/lib/NG2memcpy.S b/arch/sparc/lib/NG2memcpy.S
index 0aed75653b50..03eadf66b0d3 100644
--- a/arch/sparc/lib/NG2memcpy.S
+++ b/arch/sparc/lib/NG2memcpy.S
@@ -90,49 +90,49 @@
 	faligndata	%x7, %x8, %f14;
 
 #define FREG_MOVE_1(x0) \
-	fmovd		%x0, %f0;
+	fsrc2		%x0, %f0;
 #define FREG_MOVE_2(x0, x1) \
-	fmovd		%x0, %f0; \
-	fmovd		%x1, %f2;
+	fsrc2		%x0, %f0; \
+	fsrc2		%x1, %f2;
 #define FREG_MOVE_3(x0, x1, x2) \
-	fmovd		%x0, %f0; \
-	fmovd		%x1, %f2; \
-	fmovd		%x2, %f4;
+	fsrc2		%x0, %f0; \
+	fsrc2		%x1, %f2; \
+	fsrc2		%x2, %f4;
 #define FREG_MOVE_4(x0, x1, x2, x3) \
-	fmovd		%x0, %f0; \
-	fmovd		%x1, %f2; \
-	fmovd		%x2, %f4; \
-	fmovd		%x3, %f6;
+	fsrc2		%x0, %f0; \
+	fsrc2		%x1, %f2; \
+	fsrc2		%x2, %f4; \
+	fsrc2		%x3, %f6;
 #define FREG_MOVE_5(x0, x1, x2, x3, x4) \
-	fmovd		%x0, %f0; \
-	fmovd		%x1, %f2; \
-	fmovd		%x2, %f4; \
-	fmovd		%x3, %f6; \
-	fmovd		%x4, %f8;
+	fsrc2		%x0, %f0; \
+	fsrc2		%x1, %f2; \
+	fsrc2		%x2, %f4; \
+	fsrc2		%x3, %f6; \
+	fsrc2		%x4, %f8;
 #define FREG_MOVE_6(x0, x1, x2, x3, x4, x5) \
-	fmovd		%x0, %f0; \
-	fmovd		%x1, %f2; \
-	fmovd		%x2, %f4; \
-	fmovd		%x3, %f6; \
-	fmovd		%x4, %f8; \
-	fmovd		%x5, %f10;
+	fsrc2		%x0, %f0; \
+	fsrc2		%x1, %f2; \
+	fsrc2		%x2, %f4; \
+	fsrc2		%x3, %f6; \
+	fsrc2		%x4, %f8; \
+	fsrc2		%x5, %f10;
 #define FREG_MOVE_7(x0, x1, x2, x3, x4, x5, x6) \
-	fmovd		%x0, %f0; \
-	fmovd		%x1, %f2; \
-	fmovd		%x2, %f4; \
-	fmovd		%x3, %f6; \
-	fmovd		%x4, %f8; \
-	fmovd		%x5, %f10; \
-	fmovd		%x6, %f12;
+	fsrc2		%x0, %f0; \
+	fsrc2		%x1, %f2; \
+	fsrc2		%x2, %f4; \
+	fsrc2		%x3, %f6; \
+	fsrc2		%x4, %f8; \
+	fsrc2		%x5, %f10; \
+	fsrc2		%x6, %f12;
 #define FREG_MOVE_8(x0, x1, x2, x3, x4, x5, x6, x7) \
-	fmovd		%x0, %f0; \
-	fmovd		%x1, %f2; \
-	fmovd		%x2, %f4; \
-	fmovd		%x3, %f6; \
-	fmovd		%x4, %f8; \
-	fmovd		%x5, %f10; \
-	fmovd		%x6, %f12; \
-	fmovd		%x7, %f14;
+	fsrc2		%x0, %f0; \
+	fsrc2		%x1, %f2; \
+	fsrc2		%x2, %f4; \
+	fsrc2		%x3, %f6; \
+	fsrc2		%x4, %f8; \
+	fsrc2		%x5, %f10; \
+	fsrc2		%x6, %f12; \
+	fsrc2		%x7, %f14;
 #define FREG_LOAD_1(base, x0) \
 	EX_LD(LOAD(ldd, base + 0x00, %x0))
 #define FREG_LOAD_2(base, x0, x1) \
diff --git a/arch/sparc/lib/U1memcpy.S b/arch/sparc/lib/U1memcpy.S
index bafd2fc07acb..b67142b7768e 100644
--- a/arch/sparc/lib/U1memcpy.S
+++ b/arch/sparc/lib/U1memcpy.S
@@ -109,7 +109,7 @@
 #define UNEVEN_VISCHUNK_LAST(dest, f0, f1, left)	\
 	subcc			%left, 8, %left;	\
 	bl,pn			%xcc, 95f;		\
-	 fsrc1			%f0, %f1;
+	 fsrc2			%f0, %f1;
 
 #define UNEVEN_VISCHUNK(dest, f0, f1, left)		\
 	UNEVEN_VISCHUNK_LAST(dest, f0, f1, left)	\
@@ -201,7 +201,7 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
 	andn		%o1, (0x40 - 1), %o1
 	and		%g2, 7, %g2
 	andncc		%g3, 0x7, %g3
-	fmovd		%f0, %f2
+	fsrc2		%f0, %f2
 	sub		%g3, 0x8, %g3
 	sub		%o2, %GLOBAL_SPARE, %o2
 
diff --git a/arch/sparc/lib/copy_page.S b/arch/sparc/lib/copy_page.S
index b243d3b606ba..4d2df328e514 100644
--- a/arch/sparc/lib/copy_page.S
+++ b/arch/sparc/lib/copy_page.S
@@ -34,10 +34,10 @@
 #endif
 
 #define TOUCH(reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7)	\
-	fmovd	%reg0, %f48; 	fmovd	%reg1, %f50;		\
-	fmovd	%reg2, %f52; 	fmovd	%reg3, %f54;		\
-	fmovd	%reg4, %f56; 	fmovd	%reg5, %f58;		\
-	fmovd	%reg6, %f60; 	fmovd	%reg7, %f62;
+	fsrc2	%reg0, %f48; 	fsrc2	%reg1, %f50;		\
+	fsrc2	%reg2, %f52; 	fsrc2	%reg3, %f54;		\
+	fsrc2	%reg4, %f56; 	fsrc2	%reg5, %f58;		\
+	fsrc2	%reg6, %f60; 	fsrc2	%reg7, %f62;
 
 	.text
 
@@ -104,60 +104,60 @@ cheetah_copy_page_insn:
 	prefetch	[%o1 + 0x140], #one_read
 	ldd		[%o1 + 0x010], %f4
 	prefetch	[%o1 + 0x180], #one_read
-	fmovd		%f0, %f16
+	fsrc2		%f0, %f16
 	ldd		[%o1 + 0x018], %f6
-	fmovd		%f2, %f18
+	fsrc2		%f2, %f18
 	ldd		[%o1 + 0x020], %f8
-	fmovd		%f4, %f20
+	fsrc2		%f4, %f20
 	ldd		[%o1 + 0x028], %f10
-	fmovd		%f6, %f22
+	fsrc2		%f6, %f22
 	ldd		[%o1 + 0x030], %f12
-	fmovd		%f8, %f24
+	fsrc2		%f8, %f24
 	ldd		[%o1 + 0x038], %f14
-	fmovd		%f10, %f26
+	fsrc2		%f10, %f26
 	ldd		[%o1 + 0x040], %f0
 1:	ldd		[%o1 + 0x048], %f2
-	fmovd		%f12, %f28
+	fsrc2		%f12, %f28
 	ldd		[%o1 + 0x050], %f4
-	fmovd		%f14, %f30
+	fsrc2		%f14, %f30
 	stda		%f16, [%o0] ASI_BLK_P
 	ldd		[%o1 + 0x058], %f6
-	fmovd		%f0, %f16
+	fsrc2		%f0, %f16
 	ldd		[%o1 + 0x060], %f8
-	fmovd		%f2, %f18
+	fsrc2		%f2, %f18
 	ldd		[%o1 + 0x068], %f10
-	fmovd		%f4, %f20
+	fsrc2		%f4, %f20
 	ldd		[%o1 + 0x070], %f12
-	fmovd		%f6, %f22
+	fsrc2		%f6, %f22
 	ldd		[%o1 + 0x078], %f14
-	fmovd		%f8, %f24
+	fsrc2		%f8, %f24
 	ldd		[%o1 + 0x080], %f0
 	prefetch	[%o1 + 0x180], #one_read
-	fmovd		%f10, %f26
+	fsrc2		%f10, %f26
 	subcc		%o2, 1, %o2
 	add		%o0, 0x40, %o0
 	bne,pt		%xcc, 1b
 	 add		%o1, 0x40, %o1
 
 	ldd		[%o1 + 0x048], %f2
-	fmovd		%f12, %f28
+	fsrc2		%f12, %f28
 	ldd		[%o1 + 0x050], %f4
-	fmovd		%f14, %f30
+	fsrc2		%f14, %f30
 	stda		%f16, [%o0] ASI_BLK_P
 	ldd		[%o1 + 0x058], %f6
-	fmovd		%f0, %f16
+	fsrc2		%f0, %f16
 	ldd		[%o1 + 0x060], %f8
-	fmovd		%f2, %f18
+	fsrc2		%f2, %f18
 	ldd		[%o1 + 0x068], %f10
-	fmovd		%f4, %f20
+	fsrc2		%f4, %f20
 	ldd		[%o1 + 0x070], %f12
-	fmovd		%f6, %f22
+	fsrc2		%f6, %f22
 	add		%o0, 0x40, %o0
 	ldd		[%o1 + 0x078], %f14
-	fmovd		%f8, %f24
-	fmovd		%f10, %f26
-	fmovd		%f12, %f28
-	fmovd		%f14, %f30
+	fsrc2		%f8, %f24
+	fsrc2		%f10, %f26
+	fsrc2		%f12, %f28
+	fsrc2		%f14, %f30
 	stda		%f16, [%o0] ASI_BLK_P
 	membar		#Sync
 	VISExitHalf
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index f46cf6be3370..77ac917be152 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -32,24 +32,6 @@
 
 int show_unhandled_signals = 1;
 
-/* At boot time we determine these two values necessary for setting
- * up the segment maps and page table entries (pte's).
- */
-
-int num_contexts;
-
-/* Return how much physical memory we have.  */
-unsigned long probe_memory(void)
-{
-	unsigned long total = 0;
-	int i;
-
-	for (i = 0; sp_banks[i].num_bytes; i++)
-		total += sp_banks[i].num_bytes;
-
-	return total;
-}
-
 static void unhandled_fault(unsigned long, struct task_struct *,
 		struct pt_regs *) __attribute__ ((noreturn));
 
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
index 055c66cf1bf4..449f864f0cef 100644
--- a/arch/sparc/mm/highmem.c
+++ b/arch/sparc/mm/highmem.c
@@ -22,13 +22,31 @@
  * shared by CPUs, and so precious, and establishing them requires IPI.
  * Atomic kmaps are lightweight and we may have NCPUS more of them.
  */
-#include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/export.h>
-#include <asm/pgalloc.h>
+#include <linux/mm.h>
+
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
-#include <asm/fixmap.h>
+#include <asm/pgalloc.h>
+#include <asm/vaddrs.h>
+
+pgprot_t kmap_prot;
+
+static pte_t *kmap_pte;
+
+void __init kmap_init(void)
+{
+	unsigned long address;
+	pmd_t *dir;
+
+	address = __fix_to_virt(FIX_KMAP_BEGIN);
+	dir = pmd_offset(pgd_offset_k(address), address);
+
+        /* cache the first kmap pte */
+        kmap_pte = pte_offset_kernel(dir, address);
+        kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE);
+}
 
 void *kmap_atomic(struct page *page)
 {
@@ -110,21 +128,3 @@ void __kunmap_atomic(void *kvaddr)
 	pagefault_enable();
 }
 EXPORT_SYMBOL(__kunmap_atomic);
-
-/* We may be fed a pagetable here by ptep_to_xxx and others. */
-struct page *kmap_atomic_to_page(void *ptr)
-{
-	unsigned long idx, vaddr = (unsigned long)ptr;
-	pte_t *pte;
-
-	if (vaddr < SRMMU_NOCACHE_VADDR)
-		return virt_to_page(ptr);
-	if (vaddr < PKMAP_BASE)
-		return pfn_to_page(__nocache_pa(vaddr) >> PAGE_SHIFT);
-	BUG_ON(vaddr < FIXADDR_START);
-	BUG_ON(vaddr > FIXADDR_TOP);
-
-	idx = virt_to_fix(vaddr);
-	pte = kmap_pte - (idx - FIX_KMAP_BEGIN);
-	return pte_page(*pte);
-}
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index ef5c779ec855..dde85ef1c56d 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -45,9 +45,6 @@ unsigned long pfn_base;
 EXPORT_SYMBOL(pfn_base);
 
 struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1];
-unsigned long sparc_unmapped_base;
-
-struct pgtable_cache_struct pgt_quicklists;
 
 /* Initial ramdisk setup */
 extern unsigned int sparc_ramdisk_image;
@@ -55,19 +52,6 @@ extern unsigned int sparc_ramdisk_size;
 
 unsigned long highstart_pfn, highend_pfn;
 
-pte_t *kmap_pte;
-pgprot_t kmap_prot;
-
-#define kmap_get_fixmap_pte(vaddr) \
-	pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
-
-void __init kmap_init(void)
-{
-	/* cache the first kmap pte */
-	kmap_pte = kmap_get_fixmap_pte(__fix_to_virt(FIX_KMAP_BEGIN));
-	kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE);
-}
-
 void show_mem(unsigned int filter)
 {
 	printk("Mem-info:\n");
@@ -76,33 +60,8 @@ void show_mem(unsigned int filter)
 	       nr_swap_pages << (PAGE_SHIFT-10));
 	printk("%ld pages of RAM\n", totalram_pages);
 	printk("%ld free pages\n", nr_free_pages());
-#if 0 /* undefined pgtable_cache_size, pgd_cache_size */
-	printk("%ld pages in page table cache\n",pgtable_cache_size);
-#ifndef CONFIG_SMP
-	if (sparc_cpu_model == sun4m || sparc_cpu_model == sun4d)
-		printk("%ld entries in page dir cache\n",pgd_cache_size);
-#endif	
-#endif
 }
 
-void __init sparc_context_init(int numctx)
-{
-	int ctx;
-
-	ctx_list_pool = __alloc_bootmem(numctx * sizeof(struct ctx_list), SMP_CACHE_BYTES, 0UL);
-
-	for(ctx = 0; ctx < numctx; ctx++) {
-		struct ctx_list *clist;
-
-		clist = (ctx_list_pool + ctx);
-		clist->ctx_number = ctx;
-		clist->ctx_mm = NULL;
-	}
-	ctx_free.next = ctx_free.prev = &ctx_free;
-	ctx_used.next = ctx_used.prev = &ctx_used;
-	for(ctx = 0; ctx < numctx; ctx++)
-		add_to_free_ctxlist(ctx_list_pool + ctx);
-}
 
 extern unsigned long cmdline_memory_size;
 unsigned long last_valid_pfn;
@@ -292,22 +251,7 @@ extern void device_scan(void);
 
 void __init paging_init(void)
 {
-	switch(sparc_cpu_model) {
-	case sparc_leon:
-		leon_init();
-		/* fall through */
-	case sun4m:
-	case sun4d:
-		srmmu_paging_init();
-		sparc_unmapped_base = 0x50000000;
-		break;
-	default:
-		prom_printf("paging_init: Cannot init paging on this Sparc\n");
-		prom_printf("paging_init: sparc_cpu_model = %d\n", sparc_cpu_model);
-		prom_printf("paging_init: Halting...\n");
-		prom_halt();
-	}
-
+	srmmu_paging_init();
 	prom_build_devicetree();
 	of_fill_in_cpu_data();
 	device_scan();
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 62e3f5773303..c38bb72e3e80 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -8,45 +8,45 @@
  * Copyright (C) 1999,2000 Anton Blanchard (anton@samba.org)
  */
 
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/pagemap.h>
-#include <linux/init.h>
+#include <linux/seq_file.h>
 #include <linux/spinlock.h>
 #include <linux/bootmem.h>
-#include <linux/fs.h>
-#include <linux/seq_file.h>
+#include <linux/pagemap.h>
+#include <linux/vmalloc.h>
 #include <linux/kdebug.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
 #include <linux/log2.h>
 #include <linux/gfp.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
 
-#include <asm/bitext.h>
-#include <asm/page.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/io-unit.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
-#include <asm/io.h>
+#include <asm/bitext.h>
 #include <asm/vaddrs.h>
-#include <asm/traps.h>
-#include <asm/smp.h>
-#include <asm/mbus.h>
 #include <asm/cache.h>
+#include <asm/traps.h>
 #include <asm/oplib.h>
+#include <asm/mbus.h>
+#include <asm/page.h>
 #include <asm/asi.h>
 #include <asm/msi.h>
-#include <asm/mmu_context.h>
-#include <asm/io-unit.h>
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
+#include <asm/smp.h>
+#include <asm/io.h>
 
 /* Now the cpu specific definitions. */
-#include <asm/viking.h>
-#include <asm/mxcc.h>
-#include <asm/ross.h>
+#include <asm/turbosparc.h>
 #include <asm/tsunami.h>
+#include <asm/viking.h>
 #include <asm/swift.h>
-#include <asm/turbosparc.h>
 #include <asm/leon.h>
+#include <asm/mxcc.h>
+#include <asm/ross.h>
 
 #include "srmmu.h"
 
@@ -55,10 +55,6 @@ static unsigned int hwbug_bitmask;
 int vac_cache_size;
 int vac_line_size;
 
-struct ctx_list *ctx_list_pool;
-struct ctx_list ctx_free;
-struct ctx_list ctx_used;
-
 extern struct resource sparc_iomap;
 
 extern unsigned long last_valid_pfn;
@@ -136,8 +132,8 @@ void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep)
 	}
 }
 
-/* Find an entry in the third-level page table.. */ 
-pte_t *pte_offset_kernel(pmd_t * dir, unsigned long address)
+/* Find an entry in the third-level page table.. */
+pte_t *pte_offset_kernel(pmd_t *dir, unsigned long address)
 {
 	void *pte;
 
@@ -151,55 +147,61 @@ pte_t *pte_offset_kernel(pmd_t * dir, unsigned long address)
  * align: bytes, number to align at.
  * Returns the virtual address of the allocated area.
  */
-static unsigned long __srmmu_get_nocache(int size, int align)
+static void *__srmmu_get_nocache(int size, int align)
 {
 	int offset;
+	unsigned long addr;
 
 	if (size < SRMMU_NOCACHE_BITMAP_SHIFT) {
-		printk("Size 0x%x too small for nocache request\n", size);
+		printk(KERN_ERR "Size 0x%x too small for nocache request\n",
+		       size);
 		size = SRMMU_NOCACHE_BITMAP_SHIFT;
 	}
-	if (size & (SRMMU_NOCACHE_BITMAP_SHIFT-1)) {
-		printk("Size 0x%x unaligned int nocache request\n", size);
-		size += SRMMU_NOCACHE_BITMAP_SHIFT-1;
+	if (size & (SRMMU_NOCACHE_BITMAP_SHIFT - 1)) {
+		printk(KERN_ERR "Size 0x%x unaligned int nocache request\n",
+		       size);
+		size += SRMMU_NOCACHE_BITMAP_SHIFT - 1;
 	}
 	BUG_ON(align > SRMMU_NOCACHE_ALIGN_MAX);
 
 	offset = bit_map_string_get(&srmmu_nocache_map,
-		       			size >> SRMMU_NOCACHE_BITMAP_SHIFT,
-					align >> SRMMU_NOCACHE_BITMAP_SHIFT);
+				    size >> SRMMU_NOCACHE_BITMAP_SHIFT,
+				    align >> SRMMU_NOCACHE_BITMAP_SHIFT);
 	if (offset == -1) {
-		printk("srmmu: out of nocache %d: %d/%d\n",
-		    size, (int) srmmu_nocache_size,
-		    srmmu_nocache_map.used << SRMMU_NOCACHE_BITMAP_SHIFT);
+		printk(KERN_ERR "srmmu: out of nocache %d: %d/%d\n",
+		       size, (int) srmmu_nocache_size,
+		       srmmu_nocache_map.used << SRMMU_NOCACHE_BITMAP_SHIFT);
 		return 0;
 	}
 
-	return (SRMMU_NOCACHE_VADDR + (offset << SRMMU_NOCACHE_BITMAP_SHIFT));
+	addr = SRMMU_NOCACHE_VADDR + (offset << SRMMU_NOCACHE_BITMAP_SHIFT);
+	return (void *)addr;
 }
 
-unsigned long srmmu_get_nocache(int size, int align)
+void *srmmu_get_nocache(int size, int align)
 {
-	unsigned long tmp;
+	void *tmp;
 
 	tmp = __srmmu_get_nocache(size, align);
 
 	if (tmp)
-		memset((void *)tmp, 0, size);
+		memset(tmp, 0, size);
 
 	return tmp;
 }
 
-void srmmu_free_nocache(unsigned long vaddr, int size)
+void srmmu_free_nocache(void *addr, int size)
 {
+	unsigned long vaddr;
 	int offset;
 
+	vaddr = (unsigned long)addr;
 	if (vaddr < SRMMU_NOCACHE_VADDR) {
 		printk("Vaddr %lx is smaller than nocache base 0x%lx\n",
 		    vaddr, (unsigned long)SRMMU_NOCACHE_VADDR);
 		BUG();
 	}
-	if (vaddr+size > srmmu_nocache_end) {
+	if (vaddr + size > srmmu_nocache_end) {
 		printk("Vaddr %lx is bigger than nocache end 0x%lx\n",
 		    vaddr, srmmu_nocache_end);
 		BUG();
@@ -212,7 +214,7 @@ void srmmu_free_nocache(unsigned long vaddr, int size)
 		printk("Size 0x%x is too small\n", size);
 		BUG();
 	}
-	if (vaddr & (size-1)) {
+	if (vaddr & (size - 1)) {
 		printk("Vaddr %lx is not aligned to size 0x%x\n", vaddr, size);
 		BUG();
 	}
@@ -226,13 +228,23 @@ void srmmu_free_nocache(unsigned long vaddr, int size)
 static void srmmu_early_allocate_ptable_skeleton(unsigned long start,
 						 unsigned long end);
 
-extern unsigned long probe_memory(void);	/* in fault.c */
+/* Return how much physical memory we have.  */
+static unsigned long __init probe_memory(void)
+{
+	unsigned long total = 0;
+	int i;
+
+	for (i = 0; sp_banks[i].num_bytes; i++)
+		total += sp_banks[i].num_bytes;
+
+	return total;
+}
 
 /*
  * Reserve nocache dynamically proportionally to the amount of
  * system RAM. -- Tomas Szepe <szepe@pinerecords.com>, June 2002
  */
-static void srmmu_nocache_calcsize(void)
+static void __init srmmu_nocache_calcsize(void)
 {
 	unsigned long sysmemavail = probe_memory() / 1024;
 	int srmmu_nocache_npages;
@@ -271,7 +283,7 @@ static void __init srmmu_nocache_init(void)
 	srmmu_nocache_bitmap = __alloc_bootmem(bitmap_bits >> 3, SMP_CACHE_BYTES, 0UL);
 	bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits);
 
-	srmmu_swapper_pg_dir = (pgd_t *)__srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE);
+	srmmu_swapper_pg_dir = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE);
 	memset(__nocache_fix(srmmu_swapper_pg_dir), 0, SRMMU_PGD_TABLE_SIZE);
 	init_mm.pgd = srmmu_swapper_pg_dir;
 
@@ -304,7 +316,7 @@ pgd_t *get_pgd_fast(void)
 {
 	pgd_t *pgd = NULL;
 
-	pgd = (pgd_t *)__srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE);
+	pgd = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE);
 	if (pgd) {
 		pgd_t *init = pgd_offset_k(0);
 		memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
@@ -330,7 +342,7 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
 
 	if ((pte = (unsigned long)pte_alloc_one_kernel(mm, address)) == 0)
 		return NULL;
-	page = pfn_to_page( __nocache_pa(pte) >> PAGE_SHIFT );
+	page = pfn_to_page(__nocache_pa(pte) >> PAGE_SHIFT);
 	pgtable_page_ctor(page);
 	return page;
 }
@@ -344,18 +356,50 @@ void pte_free(struct mm_struct *mm, pgtable_t pte)
 	if (p == 0)
 		BUG();
 	p = page_to_pfn(pte) << PAGE_SHIFT;	/* Physical address */
-	p = (unsigned long) __nocache_va(p);	/* Nocached virtual */
-	srmmu_free_nocache(p, PTE_SIZE);
+
+	/* free non cached virtual address*/
+	srmmu_free_nocache(__nocache_va(p), PTE_SIZE);
 }
 
-/*
- */
+/* context handling - a dynamically sized pool is used */
+#define NO_CONTEXT	-1
+
+struct ctx_list {
+	struct ctx_list *next;
+	struct ctx_list *prev;
+	unsigned int ctx_number;
+	struct mm_struct *ctx_mm;
+};
+
+static struct ctx_list *ctx_list_pool;
+static struct ctx_list ctx_free;
+static struct ctx_list ctx_used;
+
+/* At boot time we determine the number of contexts */
+static int num_contexts;
+
+static inline void remove_from_ctx_list(struct ctx_list *entry)
+{
+	entry->next->prev = entry->prev;
+	entry->prev->next = entry->next;
+}
+
+static inline void add_to_ctx_list(struct ctx_list *head, struct ctx_list *entry)
+{
+	entry->next = head;
+	(entry->prev = head->prev)->next = entry;
+	head->prev = entry;
+}
+#define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry)
+#define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry)
+
+
 static inline void alloc_context(struct mm_struct *old_mm, struct mm_struct *mm)
 {
 	struct ctx_list *ctxp;
 
 	ctxp = ctx_free.next;
-	if(ctxp != &ctx_free) {
+	if (ctxp != &ctx_free) {
 		remove_from_ctx_list(ctxp);
 		add_to_used_ctxlist(ctxp);
 		mm->context = ctxp->ctx_number;
@@ -363,9 +407,9 @@ static inline void alloc_context(struct mm_struct *old_mm, struct mm_struct *mm)
 		return;
 	}
 	ctxp = ctx_used.next;
-	if(ctxp->ctx_mm == old_mm)
+	if (ctxp->ctx_mm == old_mm)
 		ctxp = ctxp->next;
-	if(ctxp == &ctx_used)
+	if (ctxp == &ctx_used)
 		panic("out of mmu contexts");
 	flush_cache_mm(ctxp->ctx_mm);
 	flush_tlb_mm(ctxp->ctx_mm);
@@ -385,11 +429,31 @@ static inline void free_context(int context)
 	add_to_free_ctxlist(ctx_old);
 }
 
+static void __init sparc_context_init(int numctx)
+{
+	int ctx;
+	unsigned long size;
+
+	size = numctx * sizeof(struct ctx_list);
+	ctx_list_pool = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
+
+	for (ctx = 0; ctx < numctx; ctx++) {
+		struct ctx_list *clist;
+
+		clist = (ctx_list_pool + ctx);
+		clist->ctx_number = ctx;
+		clist->ctx_mm = NULL;
+	}
+	ctx_free.next = ctx_free.prev = &ctx_free;
+	ctx_used.next = ctx_used.prev = &ctx_used;
+	for (ctx = 0; ctx < numctx; ctx++)
+		add_to_free_ctxlist(ctx_list_pool + ctx);
+}
 
 void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm,
 	       struct task_struct *tsk)
 {
-	if(mm->context == NO_CONTEXT) {
+	if (mm->context == NO_CONTEXT) {
 		spin_lock(&srmmu_context_spinlock);
 		alloc_context(old_mm, mm);
 		spin_unlock(&srmmu_context_spinlock);
@@ -407,7 +471,7 @@ void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm,
 
 /* Low level IO area allocation on the SRMMU. */
 static inline void srmmu_mapioaddr(unsigned long physaddr,
-    unsigned long virt_addr, int bus_type)
+				   unsigned long virt_addr, int bus_type)
 {
 	pgd_t *pgdp;
 	pmd_t *pmdp;
@@ -420,8 +484,7 @@ static inline void srmmu_mapioaddr(unsigned long physaddr,
 	ptep = pte_offset_kernel(pmdp, virt_addr);
 	tmp = (physaddr >> 4) | SRMMU_ET_PTE;
 
-	/*
-	 * I need to test whether this is consistent over all
+	/* I need to test whether this is consistent over all
 	 * sun4m's.  The bus_type represents the upper 4 bits of
 	 * 36-bit physical address on the I/O space lines...
 	 */
@@ -591,10 +654,10 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start,
 	pmd_t *pmdp;
 	pte_t *ptep;
 
-	while(start < end) {
+	while (start < end) {
 		pgdp = pgd_offset_k(start);
 		if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
-			pmdp = (pmd_t *) __srmmu_get_nocache(
+			pmdp = __srmmu_get_nocache(
 			    SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
 			if (pmdp == NULL)
 				early_pgtable_allocfail("pmd");
@@ -602,8 +665,8 @@ static void __init srmmu_early_allocate_ptable_skeleton(unsigned long start,
 			pgd_set(__nocache_fix(pgdp), pmdp);
 		}
 		pmdp = pmd_offset(__nocache_fix(pgdp), start);
-		if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
-			ptep = (pte_t *)__srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
+		if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
+			ptep = __srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
 			if (ptep == NULL)
 				early_pgtable_allocfail("pte");
 			memset(__nocache_fix(ptep), 0, PTE_SIZE);
@@ -622,18 +685,18 @@ static void __init srmmu_allocate_ptable_skeleton(unsigned long start,
 	pmd_t *pmdp;
 	pte_t *ptep;
 
-	while(start < end) {
+	while (start < end) {
 		pgdp = pgd_offset_k(start);
 		if (pgd_none(*pgdp)) {
-			pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
+			pmdp = __srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
 			if (pmdp == NULL)
 				early_pgtable_allocfail("pmd");
 			memset(pmdp, 0, SRMMU_PMD_TABLE_SIZE);
 			pgd_set(pgdp, pmdp);
 		}
 		pmdp = pmd_offset(pgdp, start);
-		if(srmmu_pmd_none(*pmdp)) {
-			ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE,
+		if (srmmu_pmd_none(*pmdp)) {
+			ptep = __srmmu_get_nocache(PTE_SIZE,
 							     PTE_SIZE);
 			if (ptep == NULL)
 				early_pgtable_allocfail("pte");
@@ -671,72 +734,76 @@ static inline unsigned long srmmu_probe(unsigned long vaddr)
 static void __init srmmu_inherit_prom_mappings(unsigned long start,
 					       unsigned long end)
 {
+	unsigned long probed;
+	unsigned long addr;
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
-	int what = 0; /* 0 = normal-pte, 1 = pmd-level pte, 2 = pgd-level pte */
-	unsigned long prompte;
+	int what; /* 0 = normal-pte, 1 = pmd-level pte, 2 = pgd-level pte */
 
-	while(start <= end) {
+	while (start <= end) {
 		if (start == 0)
 			break; /* probably wrap around */
-		if(start == 0xfef00000)
+		if (start == 0xfef00000)
 			start = KADB_DEBUGGER_BEGVM;
-		if(!(prompte = srmmu_probe(start))) {
+		probed = srmmu_probe(start);
+		if (!probed) {
+			/* continue probing until we find an entry */
 			start += PAGE_SIZE;
 			continue;
 		}
-    
+
 		/* A red snapper, see what it really is. */
 		what = 0;
-    
-		if(!(start & ~(SRMMU_REAL_PMD_MASK))) {
-			if(srmmu_probe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte)
+		addr = start - PAGE_SIZE;
+
+		if (!(start & ~(SRMMU_REAL_PMD_MASK))) {
+			if (srmmu_probe(addr + SRMMU_REAL_PMD_SIZE) == probed)
 				what = 1;
 		}
-    
-		if(!(start & ~(SRMMU_PGDIR_MASK))) {
-			if(srmmu_probe((start-PAGE_SIZE) + SRMMU_PGDIR_SIZE) ==
-			   prompte)
+
+		if (!(start & ~(SRMMU_PGDIR_MASK))) {
+			if (srmmu_probe(addr + SRMMU_PGDIR_SIZE) == probed)
 				what = 2;
 		}
-    
+
 		pgdp = pgd_offset_k(start);
-		if(what == 2) {
-			*(pgd_t *)__nocache_fix(pgdp) = __pgd(prompte);
+		if (what == 2) {
+			*(pgd_t *)__nocache_fix(pgdp) = __pgd(probed);
 			start += SRMMU_PGDIR_SIZE;
 			continue;
 		}
 		if (pgd_none(*(pgd_t *)__nocache_fix(pgdp))) {
-			pmdp = (pmd_t *)__srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
+			pmdp = __srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE,
+						   SRMMU_PMD_TABLE_SIZE);
 			if (pmdp == NULL)
 				early_pgtable_allocfail("pmd");
 			memset(__nocache_fix(pmdp), 0, SRMMU_PMD_TABLE_SIZE);
 			pgd_set(__nocache_fix(pgdp), pmdp);
 		}
 		pmdp = pmd_offset(__nocache_fix(pgdp), start);
-		if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
-			ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE,
-							     PTE_SIZE);
+		if (srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) {
+			ptep = __srmmu_get_nocache(PTE_SIZE, PTE_SIZE);
 			if (ptep == NULL)
 				early_pgtable_allocfail("pte");
 			memset(__nocache_fix(ptep), 0, PTE_SIZE);
 			pmd_set(__nocache_fix(pmdp), ptep);
 		}
-		if(what == 1) {
-			/*
-			 * We bend the rule where all 16 PTPs in a pmd_t point
+		if (what == 1) {
+			/* We bend the rule where all 16 PTPs in a pmd_t point
 			 * inside the same PTE page, and we leak a perfectly
 			 * good hardware PTE piece. Alternatives seem worse.
 			 */
 			unsigned int x;	/* Index of HW PMD in soft cluster */
+			unsigned long *val;
 			x = (start >> PMD_SHIFT) & 15;
-			*(unsigned long *)__nocache_fix(&pmdp->pmdv[x]) = prompte;
+			val = &pmdp->pmdv[x];
+			*(unsigned long *)__nocache_fix(val) = probed;
 			start += SRMMU_REAL_PMD_SIZE;
 			continue;
 		}
 		ptep = pte_offset_kernel(__nocache_fix(pmdp), start);
-		*(pte_t *)__nocache_fix(ptep) = __pte(prompte);
+		*(pte_t *)__nocache_fix(ptep) = __pte(probed);
 		start += PAGE_SIZE;
 	}
 }
@@ -765,18 +832,18 @@ static unsigned long __init map_spbank(unsigned long vbase, int sp_entry)
 
 	if (vstart < min_vaddr || vstart >= max_vaddr)
 		return vstart;
-	
+
 	if (vend > max_vaddr || vend < min_vaddr)
 		vend = max_vaddr;
 
-	while(vstart < vend) {
+	while (vstart < vend) {
 		do_large_mapping(vstart, pstart);
 		vstart += SRMMU_PGDIR_SIZE; pstart += SRMMU_PGDIR_SIZE;
 	}
 	return vstart;
 }
 
-static inline void map_kernel(void)
+static void __init map_kernel(void)
 {
 	int i;
 
@@ -789,9 +856,6 @@ static inline void map_kernel(void)
 	}
 }
 
-/* Paging initialization on the Sparc Reference MMU. */
-extern void sparc_context_init(int);
-
 void (*poke_srmmu)(void) __cpuinitdata = NULL;
 
 extern unsigned long bootmem_init(unsigned long *pages_avail);
@@ -806,6 +870,7 @@ void __init srmmu_paging_init(void)
 	pte_t *pte;
 	unsigned long pages_avail;
 
+	init_mm.context = (unsigned long) NO_CONTEXT;
 	sparc_iomap.start = SUN4M_IOBASE_VADDR;	/* 16MB of IOSPACE on all sun4m's. */
 
 	if (sparc_cpu_model == sun4d)
@@ -814,9 +879,9 @@ void __init srmmu_paging_init(void)
 		/* Find the number of contexts on the srmmu. */
 		cpunode = prom_getchild(prom_root_node);
 		num_contexts = 0;
-		while(cpunode != 0) {
+		while (cpunode != 0) {
 			prom_getstring(cpunode, "device_type", node_str, sizeof(node_str));
-			if(!strcmp(node_str, "cpu")) {
+			if (!strcmp(node_str, "cpu")) {
 				num_contexts = prom_getintdefault(cpunode, "mmu-nctx", 0x8);
 				break;
 			}
@@ -824,7 +889,7 @@ void __init srmmu_paging_init(void)
 		}
 	}
 
-	if(!num_contexts) {
+	if (!num_contexts) {
 		prom_printf("Something wrong, can't find cpu node in paging_init.\n");
 		prom_halt();
 	}
@@ -834,14 +899,14 @@ void __init srmmu_paging_init(void)
 
 	srmmu_nocache_calcsize();
 	srmmu_nocache_init();
-        srmmu_inherit_prom_mappings(0xfe400000,(LINUX_OPPROM_ENDVM-PAGE_SIZE));
+	srmmu_inherit_prom_mappings(0xfe400000, (LINUX_OPPROM_ENDVM - PAGE_SIZE));
 	map_kernel();
 
 	/* ctx table has to be physically aligned to its size */
-	srmmu_context_table = (ctxd_t *)__srmmu_get_nocache(num_contexts*sizeof(ctxd_t), num_contexts*sizeof(ctxd_t));
+	srmmu_context_table = __srmmu_get_nocache(num_contexts * sizeof(ctxd_t), num_contexts * sizeof(ctxd_t));
 	srmmu_ctx_table_phys = (ctxd_t *)__nocache_pa((unsigned long)srmmu_context_table);
 
-	for(i = 0; i < num_contexts; i++)
+	for (i = 0; i < num_contexts; i++)
 		srmmu_ctxd_set((ctxd_t *)__nocache_fix(&srmmu_context_table[i]), srmmu_swapper_pg_dir);
 
 	flush_cache_all();
@@ -897,7 +962,7 @@ void __init srmmu_paging_init(void)
 
 void mmu_info(struct seq_file *m)
 {
-	seq_printf(m, 
+	seq_printf(m,
 		   "MMU type\t: %s\n"
 		   "contexts\t: %d\n"
 		   "nocache total\t: %ld\n"
@@ -908,10 +973,16 @@ void mmu_info(struct seq_file *m)
 		   srmmu_nocache_map.used << SRMMU_NOCACHE_BITMAP_SHIFT);
 }
 
+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	mm->context = NO_CONTEXT;
+	return 0;
+}
+
 void destroy_context(struct mm_struct *mm)
 {
 
-	if(mm->context != NO_CONTEXT) {
+	if (mm->context != NO_CONTEXT) {
 		flush_cache_mm(mm);
 		srmmu_ctxd_set(&srmmu_context_table[mm->context], srmmu_swapper_pg_dir);
 		flush_tlb_mm(mm);
@@ -941,13 +1012,12 @@ static void __init init_vac_layout(void)
 #endif
 
 	nd = prom_getchild(prom_root_node);
-	while((nd = prom_getsibling(nd)) != 0) {
+	while ((nd = prom_getsibling(nd)) != 0) {
 		prom_getstring(nd, "device_type", node_str, sizeof(node_str));
-		if(!strcmp(node_str, "cpu")) {
+		if (!strcmp(node_str, "cpu")) {
 			vac_line_size = prom_getint(nd, "cache-line-size");
 			if (vac_line_size == -1) {
-				prom_printf("can't determine cache-line-size, "
-					    "halting.\n");
+				prom_printf("can't determine cache-line-size, halting.\n");
 				prom_halt();
 			}
 			cache_lines = prom_getint(nd, "cache-nlines");
@@ -958,9 +1028,9 @@ static void __init init_vac_layout(void)
 
 			vac_cache_size = cache_lines * vac_line_size;
 #ifdef CONFIG_SMP
-			if(vac_cache_size > max_size)
+			if (vac_cache_size > max_size)
 				max_size = vac_cache_size;
-			if(vac_line_size < min_line_size)
+			if (vac_line_size < min_line_size)
 				min_line_size = vac_line_size;
 			//FIXME: cpus not contiguous!!
 			cpu++;
@@ -971,7 +1041,7 @@ static void __init init_vac_layout(void)
 #endif
 		}
 	}
-	if(nd == 0) {
+	if (nd == 0) {
 		prom_printf("No CPU nodes found, halting.\n");
 		prom_halt();
 	}
@@ -1082,7 +1152,7 @@ static void __init init_swift(void)
 			     "=r" (swift_rev) :
 			     "r" (SWIFT_MASKID_ADDR), "i" (ASI_M_BYPASS));
 	srmmu_name = "Fujitsu Swift";
-	switch(swift_rev) {
+	switch (swift_rev) {
 	case 0x11:
 	case 0x20:
 	case 0x23:
@@ -1222,10 +1292,11 @@ static void __cpuinit poke_turbosparc(void)
 
 	/* Clear any crap from the cache or else... */
 	turbosparc_flush_cache_all();
-	mreg &= ~(TURBOSPARC_ICENABLE | TURBOSPARC_DCENABLE); /* Temporarily disable I & D caches */
+	/* Temporarily disable I & D caches */
+	mreg &= ~(TURBOSPARC_ICENABLE | TURBOSPARC_DCENABLE);
 	mreg &= ~(TURBOSPARC_PCENABLE);		/* Don't check parity */
 	srmmu_set_mmureg(mreg);
-	
+
 	ccreg = turbosparc_get_ccreg();
 
 #ifdef TURBOSPARC_WRITEBACK
@@ -1248,7 +1319,7 @@ static void __cpuinit poke_turbosparc(void)
 	default:
 		ccreg |= (TURBOSPARC_SCENABLE);
 	}
-	turbosparc_set_ccreg (ccreg);
+	turbosparc_set_ccreg(ccreg);
 
 	mreg |= (TURBOSPARC_ICENABLE | TURBOSPARC_DCENABLE); /* I & D caches on */
 	mreg |= (TURBOSPARC_ICSNOOP);		/* Icache snooping on */
@@ -1342,7 +1413,7 @@ static void __cpuinit poke_viking(void)
 		unsigned long bpreg;
 
 		mreg &= ~(VIKING_TCENABLE);
-		if(smp_catch++) {
+		if (smp_catch++) {
 			/* Must disable mixed-cmd mode here for other cpu's. */
 			bpreg = viking_get_bpreg();
 			bpreg &= ~(VIKING_ACTION_MIX);
@@ -1411,7 +1482,7 @@ static void __init init_viking(void)
 	unsigned long mreg = srmmu_get_mmureg();
 
 	/* Ahhh, the viking.  SRMMU VLSI abortion number two... */
-	if(mreg & VIKING_MMODE) {
+	if (mreg & VIKING_MMODE) {
 		srmmu_name = "TI Viking";
 		viking_mxcc_present = 0;
 		msi_set_sync();
@@ -1467,8 +1538,8 @@ static void __init get_srmmu_type(void)
 	}
 
 	/* Second, check for HyperSparc or Cypress. */
-	if(mod_typ == 1) {
-		switch(mod_rev) {
+	if (mod_typ == 1) {
+		switch (mod_rev) {
 		case 7:
 			/* UP or MP Hypersparc */
 			init_hypersparc();
@@ -1488,9 +1559,8 @@ static void __init get_srmmu_type(void)
 		}
 		return;
 	}
-	
-	/*
-	 * Now Fujitsu TurboSparc. It might happen that it is
+
+	/* Now Fujitsu TurboSparc. It might happen that it is
 	 * in Swift emulation mode, so we will check later...
 	 */
 	if (psr_typ == 0 && psr_vers == 5) {
@@ -1499,15 +1569,15 @@ static void __init get_srmmu_type(void)
 	}
 
 	/* Next check for Fujitsu Swift. */
-	if(psr_typ == 0 && psr_vers == 4) {
+	if (psr_typ == 0 && psr_vers == 4) {
 		phandle cpunode;
 		char node_str[128];
 
 		/* Look if it is not a TurboSparc emulating Swift... */
 		cpunode = prom_getchild(prom_root_node);
-		while((cpunode = prom_getsibling(cpunode)) != 0) {
+		while ((cpunode = prom_getsibling(cpunode)) != 0) {
 			prom_getstring(cpunode, "device_type", node_str, sizeof(node_str));
-			if(!strcmp(node_str, "cpu")) {
+			if (!strcmp(node_str, "cpu")) {
 				if (!prom_getintdefault(cpunode, "psr-implementation", 1) &&
 				    prom_getintdefault(cpunode, "psr-version", 1) == 5) {
 					init_turbosparc();
@@ -1516,13 +1586,13 @@ static void __init get_srmmu_type(void)
 				break;
 			}
 		}
-		
+
 		init_swift();
 		return;
 	}
 
 	/* Now the Viking family of srmmu. */
-	if(psr_typ == 4 &&
+	if (psr_typ == 4 &&
 	   ((psr_vers == 0) ||
 	    ((psr_vers == 1) && (mod_typ == 0) && (mod_rev == 0)))) {
 		init_viking();
@@ -1530,7 +1600,7 @@ static void __init get_srmmu_type(void)
 	}
 
 	/* Finally the Tsunami. */
-	if(psr_typ == 4 && psr_vers == 1 && (mod_typ || mod_rev)) {
+	if (psr_typ == 4 && psr_vers == 1 && (mod_typ || mod_rev)) {
 		init_tsunami();
 		return;
 	}
diff --git a/arch/sparc/prom/init_32.c b/arch/sparc/prom/init_32.c
index 26c64cea3c9c..9ac30c2b7dba 100644
--- a/arch/sparc/prom/init_32.c
+++ b/arch/sparc/prom/init_32.c
@@ -27,13 +27,10 @@ EXPORT_SYMBOL(prom_root_node);
 struct linux_nodeops *prom_nodeops;
 
 /* You must call prom_init() before you attempt to use any of the
- * routines in the prom library.  It returns 0 on success, 1 on
- * failure.  It gets passed the pointer to the PROM vector.
+ * routines in the prom library.
+ * It gets passed the pointer to the PROM vector.
  */
 
-extern void prom_meminit(void);
-extern void prom_ranges_init(void);
-
 void __init prom_init(struct linux_romvec *rp)
 {
 	romvec = rp;
diff --git a/arch/sparc/prom/init_64.c b/arch/sparc/prom/init_64.c
index 5016c5e20575..d95db755828f 100644
--- a/arch/sparc/prom/init_64.c
+++ b/arch/sparc/prom/init_64.c
@@ -22,8 +22,8 @@ int prom_stdout;
 phandle prom_chosen_node;
 
 /* You must call prom_init() before you attempt to use any of the
- * routines in the prom library.  It returns 0 on success, 1 on
- * failure.  It gets passed the pointer to the PROM vector.
+ * routines in the prom library.
+ * It gets passed the pointer to the PROM vector.
  */
 
 extern void prom_cif_init(void *, void *);