patch-2.1.115 linux/arch/sparc64/kernel/process.c

Next file: linux/arch/sparc64/kernel/psycho.c
Previous file: linux/arch/sparc64/kernel/itlb_miss.S
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.114/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
@@ -1,4 +1,4 @@
-/*  $Id: process.c,v 1.54 1998/04/28 08:23:28 davem Exp $
+/*  $Id: process.c,v 1.70 1998/08/04 20:49:15 davem Exp $
  *  arch/sparc64/kernel/process.c
  *
  *  Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -43,45 +43,6 @@
 
 #ifndef __SMP__
 
-extern int pgt_cache_water[2];
-
-static inline void ultra_check_pgt_cache(void)
-{
-        struct page *page, *page2;
-
-        if(pgtable_cache_size > pgt_cache_water[0]) {
-                do {
-                        if(pmd_quicklist)
-                                free_pmd_slow(get_pmd_fast());
-                        if(pte_quicklist)
-                                free_pte_slow(get_pte_fast());
-                } while(pgtable_cache_size > pgt_cache_water[1]);
-        }
-        if (pgd_cache_size > pgt_cache_water[0] / 4) {
-                for (page2 = NULL, page = (struct page *)pgd_quicklist; page;) {
-                        if ((unsigned long)page->pprev_hash == 3) {
-                                if (page2)
-                                        page2->next_hash = page->next_hash;
-                                else
-                                        (struct page *)pgd_quicklist = page->next_hash;
-                                page->next_hash = NULL;
-                                page->pprev_hash = NULL;
-                                pgd_cache_size -= 2;
-                                free_page(PAGE_OFFSET + (page->map_nr << PAGE_SHIFT));
-                                if (page2)
-                                        page = page2->next_hash;
-                                else
-                                        page = (struct page *)pgd_quicklist;
-                                if (pgd_cache_size <= pgt_cache_water[1] / 4)
-                                        break;
-                                continue;
-                        }
-                        page2 = page;
-                        page = page->next_hash;
-                }
-        }
-}
-
 /*
  * the idle loop on a Sparc... ;)
  */
@@ -91,10 +52,10 @@
 		return -EPERM;
 
 	/* endless idle loop with no priority at all */
-	current->priority = -100;
-	current->counter = -100;
+	current->priority = 0;
+	current->counter = 0;
 	for (;;) {
-		ultra_check_pgt_cache();
+		check_pgt_cache();
 		run_task_queue(&tq_scheduler);
 		schedule();
 	}
@@ -108,17 +69,13 @@
  */
 asmlinkage int cpu_idle(void)
 {
-	current->priority = -100;
+	current->priority = 0;
 	while(1) {
 		check_pgt_cache();
-		if(tq_scheduler) {
-			lock_kernel();
-			run_task_queue(&tq_scheduler);
-			unlock_kernel();
-		}
+		run_task_queue(&tq_scheduler);
 		barrier();
-		current->counter = -100;
-		if(need_resched)
+		current->counter = 0;
+		if(current->need_resched)
 			schedule();
 		barrier();
 	}
@@ -138,7 +95,7 @@
 extern char reboot_command [];
 
 #ifdef CONFIG_SUN_CONSOLE
-extern void console_restore_palette (void);
+extern void (*prom_palette)(int);
 extern int serial_console;
 #endif
 
@@ -148,8 +105,8 @@
 	mdelay(8);
 	cli();
 #ifdef CONFIG_SUN_CONSOLE
-	if (!serial_console)
-		console_restore_palette ();
+	if (!serial_console && prom_palette)
+		prom_palette (1);
 #endif
 	prom_halt();
 	panic("Halt failed!");
@@ -166,8 +123,8 @@
 	p = strchr (reboot_command, '\n');
 	if (p) *p = 0;
 #ifdef CONFIG_SUN_CONSOLE
-	if (!serial_console)
-		console_restore_palette ();
+	if (!serial_console && prom_palette)
+		prom_palette (1);
 #endif
 	if (cmd)
 		prom_reboot(cmd);
@@ -311,7 +268,7 @@
 	       smp_processor_id(), local_irq_count,
 	       atomic_read(&global_irq_count));
 #endif
-        printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x\n", regs->tstate,
+	printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x\n", regs->tstate,
 	       regs->tpc, regs->tnpc, regs->y);
 	printk("g0: %016lx g1: %016lx g2: %016lx g3: %016lx\n",
 	       regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
@@ -334,22 +291,22 @@
 #ifdef VERBOSE_SHOWREGS
 static void idump_from_user (unsigned int *pc)
 {
-        int i;
-        int code;
-        
-        if((((unsigned long) pc) & 3))
-        	return;
-        
-        pc -= 3;
-        for(i = -3; i < 6; i++) {
-        	get_user(code, pc);
-                printk("%c%08x%c",i?' ':'<',code,i?' ':'>');
-                pc++;
-        }
-        printk("\n");
+	int i;
+	int code;
+	
+	if((((unsigned long) pc) & 3))
+		return;
+	
+	pc -= 3;
+	for(i = -3; i < 6; i++) {
+		get_user(code, pc);
+		printk("%c%08x%c",i?' ':'<',code,i?' ':'>');
+		pc++;
+	}
+	printk("\n");
 }
 #endif
-                                                                		
+
 void show_regs(struct pt_regs *regs)
 {
 #ifdef VERBOSE_SHOWREGS
@@ -378,7 +335,7 @@
 
 void show_regs32(struct pt_regs32 *regs)
 {
-        printk("PSR: %08x PC: %08x NPC: %08x Y: %08x\n", regs->psr,
+	printk("PSR: %08x PC: %08x NPC: %08x Y: %08x\n", regs->psr,
 	       regs->pc, regs->npc, regs->y);
 	printk("g0: %08x g1: %08x g2: %08x g3: %08x\n",
 	       regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
@@ -405,7 +362,6 @@
 	printk("sig_address:       0x%016lx\n", tss->sig_address);
 	printk("sig_desc:          0x%016lx\n", tss->sig_desc);
 	printk("ksp:               0x%016lx\n", tss->ksp);
-	printk("kpc:               0x%08x\n", tss->kpc);
 
 	if (tss->w_saved) {
 		for (i = 0; i < NSWINS; i++) {
@@ -417,10 +373,6 @@
 		printk("w_saved:           0x%04x\n", tss->w_saved);
 	}
 
-	printk("sstk_info.stack:   0x%016lx\n",
-	        (unsigned long)tss->sstk_info.the_stack);
-	printk("sstk_info.status:  0x%016lx\n",
-	        (unsigned long)tss->sstk_info.cur_status);
 	printk("flags:             0x%08x\n", tss->flags);
 	printk("current_ds:        0x%016lx\n", tss->current_ds.seg);
 }
@@ -439,13 +391,10 @@
 void flush_thread(void)
 {
 	current->tss.w_saved = 0;
-	current->tss.sstk_info.cur_status = 0;
-	current->tss.sstk_info.the_stack = 0;
 
 	/* No new signal delivery by default. */
 	current->tss.new_signal = 0;
-	current->tss.flags &= ~(SPARC_FLAG_USEDFPU | SPARC_FLAG_USEDFPUL |
-			        SPARC_FLAG_USEDFPUU);
+	current->tss.fpsaved[0] = 0;
 	
 	/* Now, this task is no longer a kernel thread. */
 	current->tss.current_ds = USER_DS;
@@ -461,6 +410,8 @@
 		get_mmu_context(current);
 		spin_unlock(&scheduler_lock);
 	}
+	if (current->tss.flags & SPARC_FLAG_32BIT)
+		__asm__ __volatile__("stxa %%g0, [%0] %1" : : "r"(TSB_REG), "i"(ASI_DMMU));
 	current->tss.ctx = current->mm->context & 0x3ff;
 	spitfire_set_secondary_context (current->tss.ctx);
 	__asm__ __volatile__("flush %g6");
@@ -477,6 +428,13 @@
 		__get_user(fp, &(((struct reg_window *)psp)->ins[6]));
 	} else
 		__get_user(fp, &(((struct reg_window32 *)psp)->ins[6]));
+
+	/* Now 8-byte align the stack as this is mandatory in the
+	 * Sparc ABI due to how register windows work.  This hides
+	 * the restriction from thread libraries etc.  -DaveM
+	 */
+	csp &= ~7UL;
+
 	distance = fp - psp;
 	rval = (csp - distance);
 	if(copy_in_user(rval, psp, distance))
@@ -576,38 +534,21 @@
  *       allocate the task_struct and kernel stack in
  *       do_fork().
  */
-#ifdef __SMP__
-extern void ret_from_smpfork(void);
-#else
-extern void ret_from_syscall(void);
-#endif
-
 int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
 		struct task_struct *p, struct pt_regs *regs)
 {
-	unsigned long stack_offset;
 	char *child_trap_frame;
-	int tframe_size;
 
 	/* Calculate offset to stack_frame & pt_regs */
-	stack_offset = (((PAGE_SIZE << 1) -
-			((sizeof(unsigned int)*64) + (2*sizeof(unsigned long)))) &
-		~(64 - 1)) - (TRACEREG_SZ+REGWIN_SZ);
-	tframe_size = (TRACEREG_SZ + REGWIN_SZ) +
-		(sizeof(unsigned int) * 64) + (2 * sizeof(unsigned long));
-	child_trap_frame = ((char *)p) + stack_offset;
-	memcpy(child_trap_frame, (((struct reg_window *)regs)-1), tframe_size);
+	child_trap_frame = ((char *)p) + ((PAGE_SIZE << 1) - (TRACEREG_SZ+REGWIN_SZ));
+	memcpy(child_trap_frame, (((struct reg_window *)regs)-1), (TRACEREG_SZ+REGWIN_SZ));
 	p->tss.ksp = ((unsigned long) child_trap_frame) - STACK_BIAS;
-#ifdef __SMP__
-	p->tss.kpc = ((unsigned int) ((unsigned long) ret_from_smpfork)) - 0x8;
-#else
-	p->tss.kpc = ((unsigned int) ((unsigned long) ret_from_syscall)) - 0x8;
-#endif
 	p->tss.kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct reg_window));
 	p->tss.cwp = (regs->tstate + 1) & TSTATE_CWP;
+	p->tss.fpsaved[0] = 0;
 	if(regs->tstate & TSTATE_PRIV) {
 		p->tss.kregs->u_regs[UREG_FP] = p->tss.ksp;
-		p->tss.flags |= SPARC_FLAG_KTHREAD;
+		p->tss.flags |= (SPARC_FLAG_KTHREAD | SPARC_FLAG_NEWCHILD);
 		p->tss.current_ds = KERNEL_DS;
 		p->tss.ctx = 0;
 		__asm__ __volatile__("flushw");
@@ -617,11 +558,12 @@
 		p->tss.kregs->u_regs[UREG_G6] = (unsigned long) p;
 	} else {
 		if(current->tss.flags & SPARC_FLAG_32BIT) {
-			sp &= 0x00000000ffffffff;
-			regs->u_regs[UREG_FP] &= 0x00000000ffffffff;
+			sp &= 0x00000000ffffffffUL;
+			regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
 		}
 		p->tss.kregs->u_regs[UREG_FP] = sp;
-		p->tss.flags &= ~SPARC_FLAG_KTHREAD;
+		p->tss.flags = (p->tss.flags & ~SPARC_FLAG_KTHREAD) |
+			SPARC_FLAG_NEWCHILD;
 		p->tss.current_ds = USER_DS;
 		p->tss.ctx = (p->mm->context & 0x3ff);
 		if (sp != regs->u_regs[UREG_FP]) {
@@ -706,7 +648,8 @@
 	putname(filename);
 	if(!error) {
 		fprs_write(0);
-		regs->fprs = 0;
+		current->tss.xfsr[0] = 0;
+		current->tss.fpsaved[0] = 0;
 		regs->tstate &= ~TSTATE_PEF;
 	}
 out:

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