📄 process.c
字号:
/* $Id: process.c,v 1.113 2000/11/08 08:14:58 davem Exp $ * arch/sparc64/kernel/process.c * * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1997, 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) *//* * This file handles the architecture-dependent parts of process handling.. */#define __KERNEL_SYSCALLS__#include <stdarg.h>#include <linux/errno.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/smp.h>#include <linux/smp_lock.h>#include <linux/stddef.h>#include <linux/unistd.h>#include <linux/ptrace.h>#include <linux/malloc.h>#include <linux/user.h>#include <linux/a.out.h>#include <linux/config.h>#include <linux/reboot.h>#include <linux/delay.h>#include <asm/oplib.h>#include <asm/uaccess.h>#include <asm/system.h>#include <asm/page.h>#include <asm/pgalloc.h>#include <asm/pgtable.h>#include <asm/processor.h>#include <asm/pstate.h>#include <asm/elf.h>#include <asm/fpumacro.h>/* #define VERBOSE_SHOWREGS */#ifndef CONFIG_SMP/* * the idle loop on a Sparc... ;) */int cpu_idle(void){ if (current->pid != 0) return -EPERM; /* endless idle loop with no priority at all */ current->nice = 20; current->counter = -100; init_idle(); for (;;) { /* If current->need_resched is zero we should really * setup for a system wakup event and execute a shutdown * instruction. * * But this requires writing back the contents of the * L2 cache etc. so implement this later. -DaveM */ while (!current->need_resched) barrier(); schedule(); check_pgt_cache(); } return 0;}#else/* * the idle loop on a UltraMultiPenguin... */#define idle_me_harder() (cpu_data[current->processor].idle_volume += 1)#define unidle_me() (cpu_data[current->processor].idle_volume = 0)int cpu_idle(void){ current->nice = 20; current->counter = -100; init_idle(); while(1) { if (current->need_resched != 0) { unidle_me(); schedule(); check_pgt_cache(); } idle_me_harder(); /* The store ordering is so that IRQ handlers on * other cpus see our increasing idleness for the buddy * redistribution algorithm. -DaveM */ membar("#StoreStore | #StoreLoad"); }}#endifextern char reboot_command [];#ifdef CONFIG_SUN_CONSOLEextern void (*prom_palette)(int);extern int serial_console;#endifvoid machine_halt(void){ sti(); mdelay(8); cli();#ifdef CONFIG_SUN_CONSOLE if (!serial_console && prom_palette) prom_palette (1);#endif prom_halt(); panic("Halt failed!");}void machine_restart(char * cmd){ char *p; sti(); mdelay(8); cli(); p = strchr (reboot_command, '\n'); if (p) *p = 0;#ifdef CONFIG_SUN_CONSOLE if (!serial_console && prom_palette) prom_palette (1);#endif if (cmd) prom_reboot(cmd); if (*reboot_command) prom_reboot(reboot_command); prom_reboot(""); panic("Reboot failed!");}static void show_regwindow32(struct pt_regs *regs){ struct reg_window32 *rw; struct reg_window32 r_w; mm_segment_t old_fs; __asm__ __volatile__ ("flushw"); rw = (struct reg_window32 *)((long)(unsigned)regs->u_regs[14]); old_fs = get_fs(); set_fs (USER_DS); if (copy_from_user (&r_w, rw, sizeof(r_w))) { set_fs (old_fs); return; } rw = &r_w; set_fs (old_fs); printk("l0: %08x l1: %08x l2: %08x l3: %08x " "l4: %08x l5: %08x l6: %08x l7: %08x\n", rw->locals[0], rw->locals[1], rw->locals[2], rw->locals[3], rw->locals[4], rw->locals[5], rw->locals[6], rw->locals[7]); printk("i0: %08x i1: %08x i2: %08x i3: %08x " "i4: %08x i5: %08x i6: %08x i7: %08x\n", rw->ins[0], rw->ins[1], rw->ins[2], rw->ins[3], rw->ins[4], rw->ins[5], rw->ins[6], rw->ins[7]);}static void show_regwindow(struct pt_regs *regs){ struct reg_window *rw; struct reg_window r_w; mm_segment_t old_fs; if ((regs->tstate & TSTATE_PRIV) || !(current->thread.flags & SPARC_FLAG_32BIT)) { __asm__ __volatile__ ("flushw"); rw = (struct reg_window *)(regs->u_regs[14] + STACK_BIAS); if (!(regs->tstate & TSTATE_PRIV)) { old_fs = get_fs(); set_fs (USER_DS); if (copy_from_user (&r_w, rw, sizeof(r_w))) { set_fs (old_fs); return; } rw = &r_w; set_fs (old_fs); } } else { show_regwindow32(regs); return; } printk("l0: %016lx l1: %016lx l2: %016lx l3: %016lx\n", rw->locals[0], rw->locals[1], rw->locals[2], rw->locals[3]); printk("l4: %016lx l5: %016lx l6: %016lx l7: %016lx\n", rw->locals[4], rw->locals[5], rw->locals[6], rw->locals[7]); printk("i0: %016lx i1: %016lx i2: %016lx i3: %016lx\n", rw->ins[0], rw->ins[1], rw->ins[2], rw->ins[3]); printk("i4: %016lx i5: %016lx i6: %016lx i7: %016lx\n", rw->ins[4], rw->ins[5], rw->ins[6], rw->ins[7]);}void show_stackframe(struct sparc_stackf *sf){ unsigned long size; unsigned long *stk; int i; printk("l0: %016lx l1: %016lx l2: %016lx l3: %016lx\n" "l4: %016lx l5: %016lx l6: %016lx l7: %016lx\n", sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3], sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]); printk("i0: %016lx i1: %016lx i2: %016lx i3: %016lx\n" "i4: %016lx i5: %016lx fp: %016lx ret_pc: %016lx\n", sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3], sf->ins[4], sf->ins[5], (unsigned long)sf->fp, sf->callers_pc); printk("sp: %016lx x0: %016lx x1: %016lx x2: %016lx\n" "x3: %016lx x4: %016lx x5: %016lx xx: %016lx\n", (unsigned long)sf->structptr, sf->xargs[0], sf->xargs[1], sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5], sf->xxargs[0]); size = ((unsigned long)sf->fp) - ((unsigned long)sf); size -= STACKFRAME_SZ; stk = (unsigned long *)((unsigned long)sf + STACKFRAME_SZ); i = 0; do { printk("s%d: %016lx\n", i++, *stk++); } while ((size -= sizeof(unsigned long)));}void show_stackframe32(struct sparc_stackf32 *sf){ unsigned long size; unsigned *stk; int i; printk("l0: %08x l1: %08x l2: %08x l3: %08x\n", sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3]); printk("l4: %08x l5: %08x l6: %08x l7: %08x\n", sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]); printk("i0: %08x i1: %08x i2: %08x i3: %08x\n", sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3]); printk("i4: %08x i5: %08x fp: %08x ret_pc: %08x\n", sf->ins[4], sf->ins[5], sf->fp, sf->callers_pc); printk("sp: %08x x0: %08x x1: %08x x2: %08x\n" "x3: %08x x4: %08x x5: %08x xx: %08x\n", sf->structptr, sf->xargs[0], sf->xargs[1], sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5], sf->xxargs[0]); size = ((unsigned long)sf->fp) - ((unsigned long)sf); size -= STACKFRAME32_SZ; stk = (unsigned *)((unsigned long)sf + STACKFRAME32_SZ); i = 0; do { printk("s%d: %08x\n", i++, *stk++); } while ((size -= sizeof(unsigned)));}#ifdef CONFIG_SMPstatic spinlock_t regdump_lock = SPIN_LOCK_UNLOCKED;#endifvoid __show_regs(struct pt_regs * regs){#ifdef CONFIG_SMP unsigned long flags; spin_lock_irqsave(®dump_lock, flags); printk("CPU[%d]: local_irq_count[%u] irqs_running[%d]\n", smp_processor_id(), local_irq_count(smp_processor_id()), irqs_running());#endif 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], regs->u_regs[3]); printk("g4: %016lx g5: %016lx g6: %016lx g7: %016lx\n", regs->u_regs[4], regs->u_regs[5], regs->u_regs[6], regs->u_regs[7]); printk("o0: %016lx o1: %016lx o2: %016lx o3: %016lx\n", regs->u_regs[8], regs->u_regs[9], regs->u_regs[10], regs->u_regs[11]); printk("o4: %016lx o5: %016lx sp: %016lx ret_pc: %016lx\n", regs->u_regs[12], regs->u_regs[13], regs->u_regs[14], regs->u_regs[15]); show_regwindow(regs);#ifdef CONFIG_SMP spin_unlock_irqrestore(®dump_lock, flags);#endif}#ifdef VERBOSE_SHOWREGSstatic 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");}#endifvoid show_regs(struct pt_regs *regs){#ifdef VERBOSE_SHOWREGS extern long etrap, etraptl1;#endif __show_regs(regs);#ifdef CONFIG_SMP { extern void smp_report_regs(void); smp_report_regs(); }#endif#ifdef VERBOSE_SHOWREGS if (regs->tpc >= &etrap && regs->tpc < &etraptl1 && regs->u_regs[14] >= (long)current - PAGE_SIZE && regs->u_regs[14] < (long)current + 6 * PAGE_SIZE) { printk ("*********parent**********\n"); __show_regs((struct pt_regs *)(regs->u_regs[14] + STACK_BIAS + REGWIN_SZ)); idump_from_user(((struct pt_regs *)(regs->u_regs[14] + STACK_BIAS + REGWIN_SZ))->tpc); printk ("*********endpar**********\n"); }#endif}void show_regs32(struct pt_regs32 *regs){ 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 ", regs->u_regs[0], regs->u_regs[1], regs->u_regs[2], regs->u_regs[3]); printk("g4: %08x g5: %08x g6: %08x g7: %08x\n", regs->u_regs[4], regs->u_regs[5], regs->u_regs[6], regs->u_regs[7]); printk("o0: %08x o1: %08x o2: %08x o3: %08x ", regs->u_regs[8], regs->u_regs[9], regs->u_regs[10], regs->u_regs[11]); printk("o4: %08x o5: %08x sp: %08x ret_pc: %08x\n", regs->u_regs[12], regs->u_regs[13], regs->u_regs[14], regs->u_regs[15]);}void show_thread(struct thread_struct *thread){ int i;#if 0 printk("kregs: 0x%016lx\n", (unsigned long)thread->kregs); show_regs(thread->kregs);#endif printk("ksp: 0x%016lx\n", thread->ksp); if (thread->w_saved) { for (i = 0; i < NSWINS; i++) { if (!thread->rwbuf_stkptrs[i]) continue; printk("reg_window[%d]:\n", i); printk("stack ptr: 0x%016lx\n", thread->rwbuf_stkptrs[i]); } printk("w_saved: 0x%04x\n", thread->w_saved); } printk("flags: 0x%08x\n", thread->flags); printk("current_ds: 0x%x\n", thread->current_ds.seg);}/* Free current thread data structures etc.. */void exit_thread(void){ struct thread_struct *t = ¤t->thread; if (t->utraps) { if (t->utraps[0] < 2) kfree (t->utraps); else t->utraps[0]--; } /* Turn off performance counters if on. */ if (t->flags & SPARC_FLAG_PERFCTR) { t->user_cntd0 = t->user_cntd1 = NULL; t->pcr_reg = 0; t->flags &= ~(SPARC_FLAG_PERFCTR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -