diff options
Diffstat (limited to 'arch/mips/kernel/mips-mt.c')
| -rw-r--r-- | arch/mips/kernel/mips-mt.c | 261 |
1 files changed, 63 insertions, 198 deletions
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c index c1373a6e668..88b1ef5f868 100644 --- a/arch/mips/kernel/mips-mt.c +++ b/arch/mips/kernel/mips-mt.c @@ -1,162 +1,45 @@ /* - * General MIPS MT support routines, usable in AP/SP, SMVP, or SMTC kernels + * General MIPS MT support routines, usable in AP/SP and SMVP. * Copyright (C) 2005 Mips Technologies, Inc */ +#include <linux/device.h> #include <linux/kernel.h> #include <linux/sched.h> -#include <linux/cpumask.h> +#include <linux/export.h> #include <linux/interrupt.h> #include <linux/security.h> #include <asm/cpu.h> #include <asm/processor.h> -#include <asm/atomic.h> -#include <asm/system.h> +#include <linux/atomic.h> #include <asm/hardirq.h> #include <asm/mmu_context.h> -#include <asm/smp.h> #include <asm/mipsmtregs.h> #include <asm/r4kcache.h> #include <asm/cacheflush.h> -/* - * CPU mask used to set process affinity for MT VPEs/TCs with FPUs - */ - -cpumask_t mt_fpu_cpumask; - -#ifdef CONFIG_MIPS_MT_FPAFF - -#include <linux/cpu.h> -#include <linux/delay.h> -#include <asm/uaccess.h> - -unsigned long mt_fpemul_threshold = 0; - -/* - * Replacement functions for the sys_sched_setaffinity() and - * sys_sched_getaffinity() system calls, so that we can integrate - * FPU affinity with the user's requested processor affinity. - * This code is 98% identical with the sys_sched_setaffinity() - * and sys_sched_getaffinity() system calls, and should be - * updated when kernel/sched.c changes. - */ +int vpelimit; -/* - * find_process_by_pid - find a process with a matching PID value. - * used in sys_sched_set/getaffinity() in kernel/sched.c, so - * cloned here. - */ -static inline struct task_struct *find_process_by_pid(pid_t pid) +static int __init maxvpes(char *str) { - return pid ? find_task_by_pid(pid) : current; -} - + get_option(&str, &vpelimit); -/* - * mipsmt_sys_sched_setaffinity - set the cpu affinity of a process - */ -asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, - unsigned long __user *user_mask_ptr) -{ - cpumask_t new_mask; - cpumask_t effective_mask; - int retval; - struct task_struct *p; - - if (len < sizeof(new_mask)) - return -EINVAL; - - if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask))) - return -EFAULT; - - lock_cpu_hotplug(); - read_lock(&tasklist_lock); - - p = find_process_by_pid(pid); - if (!p) { - read_unlock(&tasklist_lock); - unlock_cpu_hotplug(); - return -ESRCH; - } - - /* - * It is not safe to call set_cpus_allowed with the - * tasklist_lock held. We will bump the task_struct's - * usage count and drop tasklist_lock before invoking - * set_cpus_allowed. - */ - get_task_struct(p); - - retval = -EPERM; - if ((current->euid != p->euid) && (current->euid != p->uid) && - !capable(CAP_SYS_NICE)) { - read_unlock(&tasklist_lock); - goto out_unlock; - } - - /* Record new user-specified CPU set for future reference */ - p->thread.user_cpus_allowed = new_mask; - - /* Unlock the task list */ - read_unlock(&tasklist_lock); - - /* Compute new global allowed CPU set if necessary */ - if( (p->thread.mflags & MF_FPUBOUND) - && cpus_intersects(new_mask, mt_fpu_cpumask)) { - cpus_and(effective_mask, new_mask, mt_fpu_cpumask); - retval = set_cpus_allowed(p, effective_mask); - } else { - p->thread.mflags &= ~MF_FPUBOUND; - retval = set_cpus_allowed(p, new_mask); - } + return 1; +} +__setup("maxvpes=", maxvpes); -out_unlock: - put_task_struct(p); - unlock_cpu_hotplug(); - return retval; -} +int tclimit; -/* - * mipsmt_sys_sched_getaffinity - get the cpu affinity of a process - */ -asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len, - unsigned long __user *user_mask_ptr) +static int __init maxtcs(char *str) { - unsigned int real_len; - cpumask_t mask; - int retval; - struct task_struct *p; - - real_len = sizeof(mask); - if (len < real_len) - return -EINVAL; - - lock_cpu_hotplug(); - read_lock(&tasklist_lock); - - retval = -ESRCH; - p = find_process_by_pid(pid); - if (!p) - goto out_unlock; - - retval = 0; - - cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map); - -out_unlock: - read_unlock(&tasklist_lock); - unlock_cpu_hotplug(); - if (retval) - return retval; - if (copy_to_user(user_mask_ptr, &mask, real_len)) - return -EFAULT; - return real_len; + get_option(&str, &tclimit); + + return 1; } -#endif /* CONFIG_MIPS_MT_FPAFF */ +__setup("maxtcs=", maxtcs); /* * Dump new MIPS MT state for the core. Does not leave TCs halted. @@ -174,9 +57,6 @@ void mips_mt_regdump(unsigned long mvpctl) int tc; unsigned long haltval; unsigned long tcstatval; -#ifdef CONFIG_MIPS_MT_SMTC - void smtc_soft_dump(void); -#endif /* CONFIG_MIPT_MT_SMTC */ local_irq_save(flags); vpflags = dvpe(); @@ -188,27 +68,32 @@ void mips_mt_regdump(unsigned long mvpctl) nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; ntc = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1; printk("-- per-VPE State --\n"); - for(i = 0; i < nvpe; i++) { - for(tc = 0; tc < ntc; tc++) { + for (i = 0; i < nvpe; i++) { + for (tc = 0; tc < ntc; tc++) { settc(tc); - if((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) { - printk(" VPE %d\n", i); - printk(" VPEControl : %08lx\n", read_vpe_c0_vpecontrol()); - printk(" VPEConf0 : %08lx\n", read_vpe_c0_vpeconf0()); - printk(" VPE%d.Status : %08lx\n", - i, read_vpe_c0_status()); - printk(" VPE%d.EPC : %08lx\n", i, read_vpe_c0_epc()); - printk(" VPE%d.Cause : %08lx\n", i, read_vpe_c0_cause()); - printk(" VPE%d.Config7 : %08lx\n", - i, read_vpe_c0_config7()); - break; /* Next VPE */ + if ((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) { + printk(" VPE %d\n", i); + printk(" VPEControl : %08lx\n", + read_vpe_c0_vpecontrol()); + printk(" VPEConf0 : %08lx\n", + read_vpe_c0_vpeconf0()); + printk(" VPE%d.Status : %08lx\n", + i, read_vpe_c0_status()); + printk(" VPE%d.EPC : %08lx %pS\n", + i, read_vpe_c0_epc(), + (void *) read_vpe_c0_epc()); + printk(" VPE%d.Cause : %08lx\n", + i, read_vpe_c0_cause()); + printk(" VPE%d.Config7 : %08lx\n", + i, read_vpe_c0_config7()); + break; /* Next VPE */ + } } - } } printk("-- per-TC State --\n"); - for(tc = 0; tc < ntc; tc++) { + for (tc = 0; tc < ntc; tc++) { settc(tc); - if(read_tc_c0_tcbind() == read_c0_tcbind()) { + if (read_tc_c0_tcbind() == read_c0_tcbind()) { /* Are we dumping ourself? */ haltval = 0; /* Then we're not halted, and mustn't be */ tcstatval = flags; /* And pre-dump TCStatus is flags */ @@ -221,24 +106,22 @@ void mips_mt_regdump(unsigned long mvpctl) } printk(" TCStatus : %08lx\n", tcstatval); printk(" TCBind : %08lx\n", read_tc_c0_tcbind()); - printk(" TCRestart : %08lx\n", read_tc_c0_tcrestart()); + printk(" TCRestart : %08lx %pS\n", + read_tc_c0_tcrestart(), (void *) read_tc_c0_tcrestart()); printk(" TCHalt : %08lx\n", haltval); printk(" TCContext : %08lx\n", read_tc_c0_tccontext()); if (!haltval) write_tc_c0_tchalt(0); } -#ifdef CONFIG_MIPS_MT_SMTC - smtc_soft_dump(); -#endif /* CONFIG_MIPT_MT_SMTC */ printk("===========================\n"); evpe(vpflags); local_irq_restore(flags); } -static int mt_opt_norps = 0; +static int mt_opt_norps; static int mt_opt_rpsctl = -1; static int mt_opt_nblsu = -1; -static int mt_opt_forceconfig7 = 0; +static int mt_opt_forceconfig7; static int mt_opt_config7 = -1; static int __init rps_disable(char *s) @@ -271,8 +154,8 @@ static int __init config7_set(char *str) __setup("config7=", config7_set); /* Experimental cache flush control parameters that should go away some day */ -int mt_protiflush = 0; -int mt_protdflush = 0; +int mt_protiflush; +int mt_protdflush; int mt_n_iflushes = 1; int mt_n_dflushes = 1; @@ -303,19 +186,8 @@ static int __init ndflush(char *s) return 1; } __setup("ndflush=", ndflush); -#ifdef CONFIG_MIPS_MT_FPAFF -static int fpaff_threshold = -1; -static int __init fpaff_thresh(char *str) -{ - get_option(&str, &fpaff_threshold); - return 1; -} - -__setup("fpaff=", fpaff_thresh); -#endif /* CONFIG_MIPS_MT_FPAFF */ - -static unsigned int itc_base = 0; +static unsigned int itc_base; static int __init set_itc_base(char *str) { @@ -331,7 +203,7 @@ void mips_mt_set_cpuoptions(void) unsigned int nconfig7 = oconfig7; if (mt_opt_norps) { - printk("\"norps\" option deprectated: use \"rpsctl=\"\n"); + printk("\"norps\" option deprecated: use \"rpsctl=\"\n"); } if (mt_opt_rpsctl >= 0) { printk("34K return prediction stack override set to %d.\n", @@ -355,7 +227,7 @@ void mips_mt_set_cpuoptions(void) if (oconfig7 != nconfig7) { __asm__ __volatile("sync"); write_c0_config7(nconfig7); - ehb (); + ehb(); printk("Config7: 0x%08x\n", read_c0_config7()); } @@ -369,20 +241,6 @@ void mips_mt_set_cpuoptions(void) if (mt_n_dflushes != 1) printk("D-Cache Flushes Repeated %d times\n", mt_n_dflushes); -#ifdef CONFIG_MIPS_MT_FPAFF - /* FPU Use Factor empirically derived from experiments on 34K */ -#define FPUSEFACTOR 333 - - if (fpaff_threshold >= 0) { - mt_fpemul_threshold = fpaff_threshold; - } else { - mt_fpemul_threshold = - (FPUSEFACTOR * (loops_per_jiffy/(500000/HZ))) / HZ; - } - printk("FPU Affinity set after %ld emulations\n", - mt_fpemul_threshold); -#endif /* CONFIG_MIPS_MT_FPAFF */ - if (itc_base != 0) { /* * Configure ITC mapping. This code is very @@ -431,20 +289,27 @@ void mips_mt_set_cpuoptions(void) void mt_cflush_lockdown(void) { -#ifdef CONFIG_MIPS_MT_SMTC - void smtc_cflush_lockdown(void); - - smtc_cflush_lockdown(); -#endif /* CONFIG_MIPS_MT_SMTC */ /* FILL IN VSMP and AP/SP VERSIONS HERE */ } void mt_cflush_release(void) { -#ifdef CONFIG_MIPS_MT_SMTC - void smtc_cflush_release(void); - - smtc_cflush_release(); -#endif /* CONFIG_MIPS_MT_SMTC */ /* FILL IN VSMP and AP/SP VERSIONS HERE */ } + +struct class *mt_class; + +static int __init mt_init(void) +{ + struct class *mtc; + + mtc = class_create(THIS_MODULE, "mt"); + if (IS_ERR(mtc)) + return PTR_ERR(mtc); + + mt_class = mtc; + + return 0; +} + +subsys_initcall(mt_init); |
