patch-2.1.37 linux/arch/sparc/mm/srmmu.c

Next file: linux/arch/sparc/mm/sun4c.c
Previous file: linux/arch/sparc/lib/irqlock.S
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.36/linux/arch/sparc/mm/srmmu.c linux/arch/sparc/mm/srmmu.c
@@ -1,4 +1,4 @@
-/* $Id: srmmu.c,v 1.136 1997/04/20 14:11:51 ecd Exp $
+/* $Id: srmmu.c,v 1.140 1997/05/01 08:53:39 davem Exp $
  * srmmu.c:  SRMMU specific routines for memory management.
  *
  * Copyright (C) 1995 David S. Miller  (davem@caip.rutgers.edu)
@@ -659,27 +659,6 @@
 	srmmu_set_entry(ptep, pte_val(pteval));
 }
 
-static void srmmu_set_pte_nocache_hyper(pte_t *ptep, pte_t pteval)
-{
-	unsigned long page = ((unsigned long)ptep) & PAGE_MASK;
-
-	srmmu_set_entry(ptep, pte_val(pteval));
-	__asm__ __volatile__("
-	lda	[%0] %2, %%g4
-	orcc	%%g4, 0x0, %%g0
-	be	2f
-	 sethi	%%hi(%7), %%g5
-1:	subcc	%%g5, %6, %%g5		! hyper_flush_cache_page
-	bne	1b
-	 sta	%%g0, [%1 + %%g5] %3
-	lda	[%4] %5, %%g0
-2:"	: /* no outputs */
-	: "r" (page | 0x400), "r" (page), "i" (ASI_M_FLUSH_PROBE),
-	  "i" (ASI_M_FLUSH_PAGE), "r" (SRMMU_FAULT_STATUS), "i" (ASI_M_MMUREGS),
-	  "r" (vac_line_size), "i" (PAGE_SIZE)
-	: "g4", "g5", "cc");
-}
-
 static void srmmu_set_pte_nocache_cypress(pte_t *ptep, pte_t pteval)
 {
 	register unsigned long a, b, c, d, e, f, g;
@@ -860,30 +839,12 @@
  */
 struct task_struct *srmmu_alloc_task_struct(void)
 {
-	return (struct task_struct *) kmalloc(sizeof(struct task_struct), GFP_KERNEL);
-}
-
-unsigned long srmmu_alloc_kernel_stack(struct task_struct *tsk)
-{
-	unsigned long kstk = __get_free_pages(GFP_KERNEL, 1, 0);
-
-	if(!kstk)
-		kstk = (unsigned long) vmalloc(PAGE_SIZE << 1);
-
-	return kstk;
+	return (struct task_struct *) __get_free_pages(GFP_KERNEL, 1, 0);
 }
 
 static void srmmu_free_task_struct(struct task_struct *tsk)
 {
-	kfree(tsk);
-}
-
-static void srmmu_free_kernel_stack(unsigned long stack)
-{
-	if(stack < VMALLOC_START)
-		free_pages(stack, 1);
-	else
-		vfree((char *)stack);
+	free_pages((unsigned long)tsk, 1);
 }
 
 /* Tsunami flushes.  It's page level tlb invalidation is not very
@@ -1365,17 +1326,28 @@
 extern void hypersparc_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end);
 extern void hypersparc_flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
 
+static void srmmu_set_pte_nocache_hyper(pte_t *ptep, pte_t pteval)
+{
+	unsigned long page = ((unsigned long)ptep) & PAGE_MASK;
+
+	srmmu_set_entry(ptep, pte_val(pteval));
+	hypersparc_flush_page_to_ram(page);
+}
+
 static void hypersparc_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp)
 {
+	srmmu_set_entry((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (srmmu_v2p((unsigned long) pgdp) >> 4))));
+	hypersparc_flush_page_to_ram((unsigned long)ctxp);
 	hyper_flush_whole_icache();
-	set_pte((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (srmmu_v2p((unsigned long) pgdp) >> 4))));
 }
 
 static void hypersparc_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp) 
 {
 	unsigned long page = ((unsigned long) pgdp) & PAGE_MASK;
 
-	hypersparc_flush_page_to_ram(page);
+	if(pgdp != swapper_pg_dir)
+		hypersparc_flush_page_to_ram(page);
+
 	if(tsk->mm->context != NO_CONTEXT) {
 		flush_cache_mm(tsk->mm);
 		ctxd_set(&srmmu_context_table[tsk->mm->context], pgdp);
@@ -1429,26 +1401,29 @@
 
 static void hypersparc_switch_to_context(struct task_struct *tsk)
 {
-	hyper_flush_whole_icache();
 	if(tsk->mm->context == NO_CONTEXT) {
+		ctxd_t *ctxp;
+
 		alloc_context(tsk->mm);
-		flush_cache_mm(tsk->mm);
-		ctxd_set(&srmmu_context_table[tsk->mm->context], tsk->mm->pgd);
-		flush_tlb_mm(tsk->mm);
+		ctxp = &srmmu_context_table[tsk->mm->context];
+		srmmu_set_entry((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (srmmu_v2p((unsigned long) tsk->mm->pgd) >> 4))));
+		hypersparc_flush_page_to_ram((unsigned long)ctxp);
 	}
+	hyper_flush_whole_icache();
 	srmmu_set_context(tsk->mm->context);
 }
 
 static void hypersparc_init_new_context(struct mm_struct *mm)
 {
-	hyper_flush_whole_icache();
+	ctxd_t *ctxp;
 
 	alloc_context(mm);
 
-	flush_cache_mm(mm);
-	ctxd_set(&srmmu_context_table[mm->context], mm->pgd);
-	flush_tlb_mm(mm);
+	ctxp = &srmmu_context_table[mm->context];
+	srmmu_set_entry((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (srmmu_v2p((unsigned long) mm->pgd) >> 4))));
+	hypersparc_flush_page_to_ram((unsigned long)ctxp);
 
+	hyper_flush_whole_icache();
 	if(mm == current->mm)
 		srmmu_set_context(mm->context);
 }
@@ -2355,13 +2330,19 @@
 static void hypersparc_destroy_context(struct mm_struct *mm)
 {
 	if(mm->context != NO_CONTEXT && mm->count == 1) {
+		ctxd_t *ctxp;
+
 		/* HyperSparc is copy-back, any data for this
 		 * process in a modified cache line is stale
 		 * and must be written back to main memory now
 		 * else we eat shit later big time.
 		 */
 		flush_cache_mm(mm);
-		ctxd_set(&srmmu_context_table[mm->context], swapper_pg_dir);
+
+		ctxp = &srmmu_context_table[mm->context];
+		srmmu_set_entry((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (srmmu_v2p((unsigned long) swapper_pg_dir) >> 4))));
+		hypersparc_flush_page_to_ram((unsigned long)ctxp);
+
 		flush_tlb_mm(mm);
 		free_context(mm->context);
 		mm->context = NO_CONTEXT;
@@ -3014,9 +2995,7 @@
         mmu_p2v = srmmu_p2v;
 
 	/* Task struct and kernel stack allocating/freeing. */
-	alloc_kernel_stack = srmmu_alloc_kernel_stack;
 	alloc_task_struct = srmmu_alloc_task_struct;
-	free_kernel_stack = srmmu_free_kernel_stack;
 	free_task_struct = srmmu_free_task_struct;
 
 	quick_kernel_fault = srmmu_quick_kernel_fault;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov