1*41c594abSRalf Baechle /* 2*41c594abSRalf Baechle * General MIPS MT support routines, usable in AP/SP, SMVP, or SMTC kernels 3*41c594abSRalf Baechle * Copyright (C) 2005 Mips Technologies, Inc 4*41c594abSRalf Baechle */ 5*41c594abSRalf Baechle 6*41c594abSRalf Baechle #include <linux/kernel.h> 7*41c594abSRalf Baechle #include <linux/sched.h> 8*41c594abSRalf Baechle #include <linux/cpumask.h> 9*41c594abSRalf Baechle #include <linux/interrupt.h> 10*41c594abSRalf Baechle 11*41c594abSRalf Baechle #include <asm/cpu.h> 12*41c594abSRalf Baechle #include <asm/processor.h> 13*41c594abSRalf Baechle #include <asm/atomic.h> 14*41c594abSRalf Baechle #include <asm/system.h> 15*41c594abSRalf Baechle #include <asm/hardirq.h> 16*41c594abSRalf Baechle #include <asm/mmu_context.h> 17*41c594abSRalf Baechle #include <asm/smp.h> 18*41c594abSRalf Baechle #include <asm/mipsmtregs.h> 19*41c594abSRalf Baechle #include <asm/r4kcache.h> 20*41c594abSRalf Baechle #include <asm/cacheflush.h> 21*41c594abSRalf Baechle 22*41c594abSRalf Baechle /* 23*41c594abSRalf Baechle * CPU mask used to set process affinity for MT VPEs/TCs with FPUs 24*41c594abSRalf Baechle */ 25*41c594abSRalf Baechle 26*41c594abSRalf Baechle cpumask_t mt_fpu_cpumask; 27*41c594abSRalf Baechle 28*41c594abSRalf Baechle #ifdef CONFIG_MIPS_MT_FPAFF 29*41c594abSRalf Baechle 30*41c594abSRalf Baechle #include <linux/cpu.h> 31*41c594abSRalf Baechle #include <linux/delay.h> 32*41c594abSRalf Baechle #include <asm/uaccess.h> 33*41c594abSRalf Baechle 34*41c594abSRalf Baechle unsigned long mt_fpemul_threshold = 0; 35*41c594abSRalf Baechle 36*41c594abSRalf Baechle /* 37*41c594abSRalf Baechle * Replacement functions for the sys_sched_setaffinity() and 38*41c594abSRalf Baechle * sys_sched_getaffinity() system calls, so that we can integrate 39*41c594abSRalf Baechle * FPU affinity with the user's requested processor affinity. 40*41c594abSRalf Baechle * This code is 98% identical with the sys_sched_setaffinity() 41*41c594abSRalf Baechle * and sys_sched_getaffinity() system calls, and should be 42*41c594abSRalf Baechle * updated when kernel/sched.c changes. 43*41c594abSRalf Baechle */ 44*41c594abSRalf Baechle 45*41c594abSRalf Baechle /* 46*41c594abSRalf Baechle * find_process_by_pid - find a process with a matching PID value. 47*41c594abSRalf Baechle * used in sys_sched_set/getaffinity() in kernel/sched.c, so 48*41c594abSRalf Baechle * cloned here. 49*41c594abSRalf Baechle */ 50*41c594abSRalf Baechle static inline task_t *find_process_by_pid(pid_t pid) 51*41c594abSRalf Baechle { 52*41c594abSRalf Baechle return pid ? find_task_by_pid(pid) : current; 53*41c594abSRalf Baechle } 54*41c594abSRalf Baechle 55*41c594abSRalf Baechle 56*41c594abSRalf Baechle /* 57*41c594abSRalf Baechle * mipsmt_sys_sched_setaffinity - set the cpu affinity of a process 58*41c594abSRalf Baechle */ 59*41c594abSRalf Baechle asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, 60*41c594abSRalf Baechle unsigned long __user *user_mask_ptr) 61*41c594abSRalf Baechle { 62*41c594abSRalf Baechle cpumask_t new_mask; 63*41c594abSRalf Baechle cpumask_t effective_mask; 64*41c594abSRalf Baechle int retval; 65*41c594abSRalf Baechle task_t *p; 66*41c594abSRalf Baechle 67*41c594abSRalf Baechle if (len < sizeof(new_mask)) 68*41c594abSRalf Baechle return -EINVAL; 69*41c594abSRalf Baechle 70*41c594abSRalf Baechle if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask))) 71*41c594abSRalf Baechle return -EFAULT; 72*41c594abSRalf Baechle 73*41c594abSRalf Baechle lock_cpu_hotplug(); 74*41c594abSRalf Baechle read_lock(&tasklist_lock); 75*41c594abSRalf Baechle 76*41c594abSRalf Baechle p = find_process_by_pid(pid); 77*41c594abSRalf Baechle if (!p) { 78*41c594abSRalf Baechle read_unlock(&tasklist_lock); 79*41c594abSRalf Baechle unlock_cpu_hotplug(); 80*41c594abSRalf Baechle return -ESRCH; 81*41c594abSRalf Baechle } 82*41c594abSRalf Baechle 83*41c594abSRalf Baechle /* 84*41c594abSRalf Baechle * It is not safe to call set_cpus_allowed with the 85*41c594abSRalf Baechle * tasklist_lock held. We will bump the task_struct's 86*41c594abSRalf Baechle * usage count and drop tasklist_lock before invoking 87*41c594abSRalf Baechle * set_cpus_allowed. 88*41c594abSRalf Baechle */ 89*41c594abSRalf Baechle get_task_struct(p); 90*41c594abSRalf Baechle 91*41c594abSRalf Baechle retval = -EPERM; 92*41c594abSRalf Baechle if ((current->euid != p->euid) && (current->euid != p->uid) && 93*41c594abSRalf Baechle !capable(CAP_SYS_NICE)) { 94*41c594abSRalf Baechle read_unlock(&tasklist_lock); 95*41c594abSRalf Baechle goto out_unlock; 96*41c594abSRalf Baechle } 97*41c594abSRalf Baechle 98*41c594abSRalf Baechle /* Record new user-specified CPU set for future reference */ 99*41c594abSRalf Baechle p->thread.user_cpus_allowed = new_mask; 100*41c594abSRalf Baechle 101*41c594abSRalf Baechle /* Unlock the task list */ 102*41c594abSRalf Baechle read_unlock(&tasklist_lock); 103*41c594abSRalf Baechle 104*41c594abSRalf Baechle /* Compute new global allowed CPU set if necessary */ 105*41c594abSRalf Baechle if( (p->thread.mflags & MF_FPUBOUND) 106*41c594abSRalf Baechle && cpus_intersects(new_mask, mt_fpu_cpumask)) { 107*41c594abSRalf Baechle cpus_and(effective_mask, new_mask, mt_fpu_cpumask); 108*41c594abSRalf Baechle retval = set_cpus_allowed(p, effective_mask); 109*41c594abSRalf Baechle } else { 110*41c594abSRalf Baechle p->thread.mflags &= ~MF_FPUBOUND; 111*41c594abSRalf Baechle retval = set_cpus_allowed(p, new_mask); 112*41c594abSRalf Baechle } 113*41c594abSRalf Baechle 114*41c594abSRalf Baechle 115*41c594abSRalf Baechle out_unlock: 116*41c594abSRalf Baechle put_task_struct(p); 117*41c594abSRalf Baechle unlock_cpu_hotplug(); 118*41c594abSRalf Baechle return retval; 119*41c594abSRalf Baechle } 120*41c594abSRalf Baechle 121*41c594abSRalf Baechle /* 122*41c594abSRalf Baechle * mipsmt_sys_sched_getaffinity - get the cpu affinity of a process 123*41c594abSRalf Baechle */ 124*41c594abSRalf Baechle asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len, 125*41c594abSRalf Baechle unsigned long __user *user_mask_ptr) 126*41c594abSRalf Baechle { 127*41c594abSRalf Baechle unsigned int real_len; 128*41c594abSRalf Baechle cpumask_t mask; 129*41c594abSRalf Baechle int retval; 130*41c594abSRalf Baechle task_t *p; 131*41c594abSRalf Baechle 132*41c594abSRalf Baechle real_len = sizeof(mask); 133*41c594abSRalf Baechle if (len < real_len) 134*41c594abSRalf Baechle return -EINVAL; 135*41c594abSRalf Baechle 136*41c594abSRalf Baechle lock_cpu_hotplug(); 137*41c594abSRalf Baechle read_lock(&tasklist_lock); 138*41c594abSRalf Baechle 139*41c594abSRalf Baechle retval = -ESRCH; 140*41c594abSRalf Baechle p = find_process_by_pid(pid); 141*41c594abSRalf Baechle if (!p) 142*41c594abSRalf Baechle goto out_unlock; 143*41c594abSRalf Baechle 144*41c594abSRalf Baechle retval = 0; 145*41c594abSRalf Baechle 146*41c594abSRalf Baechle cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map); 147*41c594abSRalf Baechle 148*41c594abSRalf Baechle out_unlock: 149*41c594abSRalf Baechle read_unlock(&tasklist_lock); 150*41c594abSRalf Baechle unlock_cpu_hotplug(); 151*41c594abSRalf Baechle if (retval) 152*41c594abSRalf Baechle return retval; 153*41c594abSRalf Baechle if (copy_to_user(user_mask_ptr, &mask, real_len)) 154*41c594abSRalf Baechle return -EFAULT; 155*41c594abSRalf Baechle return real_len; 156*41c594abSRalf Baechle } 157*41c594abSRalf Baechle 158*41c594abSRalf Baechle #endif /* CONFIG_MIPS_MT_FPAFF */ 159*41c594abSRalf Baechle 160*41c594abSRalf Baechle /* 161*41c594abSRalf Baechle * Dump new MIPS MT state for the core. Does not leave TCs halted. 162*41c594abSRalf Baechle * Takes an argument which taken to be a pre-call MVPControl value. 163*41c594abSRalf Baechle */ 164*41c594abSRalf Baechle 165*41c594abSRalf Baechle void mips_mt_regdump(unsigned long mvpctl) 166*41c594abSRalf Baechle { 167*41c594abSRalf Baechle unsigned long flags; 168*41c594abSRalf Baechle unsigned long vpflags; 169*41c594abSRalf Baechle unsigned long mvpconf0; 170*41c594abSRalf Baechle int nvpe; 171*41c594abSRalf Baechle int ntc; 172*41c594abSRalf Baechle int i; 173*41c594abSRalf Baechle int tc; 174*41c594abSRalf Baechle unsigned long haltval; 175*41c594abSRalf Baechle unsigned long tcstatval; 176*41c594abSRalf Baechle #ifdef CONFIG_MIPS_MT_SMTC 177*41c594abSRalf Baechle void smtc_soft_dump(void); 178*41c594abSRalf Baechle #endif /* CONFIG_MIPT_MT_SMTC */ 179*41c594abSRalf Baechle 180*41c594abSRalf Baechle local_irq_save(flags); 181*41c594abSRalf Baechle vpflags = dvpe(); 182*41c594abSRalf Baechle printk("=== MIPS MT State Dump ===\n"); 183*41c594abSRalf Baechle printk("-- Global State --\n"); 184*41c594abSRalf Baechle printk(" MVPControl Passed: %08lx\n", mvpctl); 185*41c594abSRalf Baechle printk(" MVPControl Read: %08lx\n", vpflags); 186*41c594abSRalf Baechle printk(" MVPConf0 : %08lx\n", (mvpconf0 = read_c0_mvpconf0())); 187*41c594abSRalf Baechle nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; 188*41c594abSRalf Baechle ntc = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1; 189*41c594abSRalf Baechle printk("-- per-VPE State --\n"); 190*41c594abSRalf Baechle for(i = 0; i < nvpe; i++) { 191*41c594abSRalf Baechle for(tc = 0; tc < ntc; tc++) { 192*41c594abSRalf Baechle settc(tc); 193*41c594abSRalf Baechle if((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) { 194*41c594abSRalf Baechle printk(" VPE %d\n", i); 195*41c594abSRalf Baechle printk(" VPEControl : %08lx\n", read_vpe_c0_vpecontrol()); 196*41c594abSRalf Baechle printk(" VPEConf0 : %08lx\n", read_vpe_c0_vpeconf0()); 197*41c594abSRalf Baechle printk(" VPE%d.Status : %08lx\n", 198*41c594abSRalf Baechle i, read_vpe_c0_status()); 199*41c594abSRalf Baechle printk(" VPE%d.EPC : %08lx\n", i, read_vpe_c0_epc()); 200*41c594abSRalf Baechle printk(" VPE%d.Cause : %08lx\n", i, read_vpe_c0_cause()); 201*41c594abSRalf Baechle printk(" VPE%d.Config7 : %08lx\n", 202*41c594abSRalf Baechle i, read_vpe_c0_config7()); 203*41c594abSRalf Baechle break; /* Next VPE */ 204*41c594abSRalf Baechle } 205*41c594abSRalf Baechle } 206*41c594abSRalf Baechle } 207*41c594abSRalf Baechle printk("-- per-TC State --\n"); 208*41c594abSRalf Baechle for(tc = 0; tc < ntc; tc++) { 209*41c594abSRalf Baechle settc(tc); 210*41c594abSRalf Baechle if(read_tc_c0_tcbind() == read_c0_tcbind()) { 211*41c594abSRalf Baechle /* Are we dumping ourself? */ 212*41c594abSRalf Baechle haltval = 0; /* Then we're not halted, and mustn't be */ 213*41c594abSRalf Baechle tcstatval = flags; /* And pre-dump TCStatus is flags */ 214*41c594abSRalf Baechle printk(" TC %d (current TC with VPE EPC above)\n", tc); 215*41c594abSRalf Baechle } else { 216*41c594abSRalf Baechle haltval = read_tc_c0_tchalt(); 217*41c594abSRalf Baechle write_tc_c0_tchalt(1); 218*41c594abSRalf Baechle tcstatval = read_tc_c0_tcstatus(); 219*41c594abSRalf Baechle printk(" TC %d\n", tc); 220*41c594abSRalf Baechle } 221*41c594abSRalf Baechle printk(" TCStatus : %08lx\n", tcstatval); 222*41c594abSRalf Baechle printk(" TCBind : %08lx\n", read_tc_c0_tcbind()); 223*41c594abSRalf Baechle printk(" TCRestart : %08lx\n", read_tc_c0_tcrestart()); 224*41c594abSRalf Baechle printk(" TCHalt : %08lx\n", haltval); 225*41c594abSRalf Baechle printk(" TCContext : %08lx\n", read_tc_c0_tccontext()); 226*41c594abSRalf Baechle if (!haltval) 227*41c594abSRalf Baechle write_tc_c0_tchalt(0); 228*41c594abSRalf Baechle } 229*41c594abSRalf Baechle #ifdef CONFIG_MIPS_MT_SMTC 230*41c594abSRalf Baechle smtc_soft_dump(); 231*41c594abSRalf Baechle #endif /* CONFIG_MIPT_MT_SMTC */ 232*41c594abSRalf Baechle printk("===========================\n"); 233*41c594abSRalf Baechle evpe(vpflags); 234*41c594abSRalf Baechle local_irq_restore(flags); 235*41c594abSRalf Baechle } 236*41c594abSRalf Baechle 237*41c594abSRalf Baechle static int mt_opt_norps = 0; 238*41c594abSRalf Baechle static int mt_opt_rpsctl = -1; 239*41c594abSRalf Baechle static int mt_opt_nblsu = -1; 240*41c594abSRalf Baechle static int mt_opt_forceconfig7 = 0; 241*41c594abSRalf Baechle static int mt_opt_config7 = -1; 242*41c594abSRalf Baechle 243*41c594abSRalf Baechle static int __init rps_disable(char *s) 244*41c594abSRalf Baechle { 245*41c594abSRalf Baechle mt_opt_norps = 1; 246*41c594abSRalf Baechle return 1; 247*41c594abSRalf Baechle } 248*41c594abSRalf Baechle __setup("norps", rps_disable); 249*41c594abSRalf Baechle 250*41c594abSRalf Baechle static int __init rpsctl_set(char *str) 251*41c594abSRalf Baechle { 252*41c594abSRalf Baechle get_option(&str, &mt_opt_rpsctl); 253*41c594abSRalf Baechle return 1; 254*41c594abSRalf Baechle } 255*41c594abSRalf Baechle __setup("rpsctl=", rpsctl_set); 256*41c594abSRalf Baechle 257*41c594abSRalf Baechle static int __init nblsu_set(char *str) 258*41c594abSRalf Baechle { 259*41c594abSRalf Baechle get_option(&str, &mt_opt_nblsu); 260*41c594abSRalf Baechle return 1; 261*41c594abSRalf Baechle } 262*41c594abSRalf Baechle __setup("nblsu=", nblsu_set); 263*41c594abSRalf Baechle 264*41c594abSRalf Baechle static int __init config7_set(char *str) 265*41c594abSRalf Baechle { 266*41c594abSRalf Baechle get_option(&str, &mt_opt_config7); 267*41c594abSRalf Baechle mt_opt_forceconfig7 = 1; 268*41c594abSRalf Baechle return 1; 269*41c594abSRalf Baechle } 270*41c594abSRalf Baechle __setup("config7=", config7_set); 271*41c594abSRalf Baechle 272*41c594abSRalf Baechle /* Experimental cache flush control parameters that should go away some day */ 273*41c594abSRalf Baechle int mt_protiflush = 0; 274*41c594abSRalf Baechle int mt_protdflush = 0; 275*41c594abSRalf Baechle int mt_n_iflushes = 1; 276*41c594abSRalf Baechle int mt_n_dflushes = 1; 277*41c594abSRalf Baechle 278*41c594abSRalf Baechle static int __init set_protiflush(char *s) 279*41c594abSRalf Baechle { 280*41c594abSRalf Baechle mt_protiflush = 1; 281*41c594abSRalf Baechle return 1; 282*41c594abSRalf Baechle } 283*41c594abSRalf Baechle __setup("protiflush", set_protiflush); 284*41c594abSRalf Baechle 285*41c594abSRalf Baechle static int __init set_protdflush(char *s) 286*41c594abSRalf Baechle { 287*41c594abSRalf Baechle mt_protdflush = 1; 288*41c594abSRalf Baechle return 1; 289*41c594abSRalf Baechle } 290*41c594abSRalf Baechle __setup("protdflush", set_protdflush); 291*41c594abSRalf Baechle 292*41c594abSRalf Baechle static int __init niflush(char *s) 293*41c594abSRalf Baechle { 294*41c594abSRalf Baechle get_option(&s, &mt_n_iflushes); 295*41c594abSRalf Baechle return 1; 296*41c594abSRalf Baechle } 297*41c594abSRalf Baechle __setup("niflush=", niflush); 298*41c594abSRalf Baechle 299*41c594abSRalf Baechle static int __init ndflush(char *s) 300*41c594abSRalf Baechle { 301*41c594abSRalf Baechle get_option(&s, &mt_n_dflushes); 302*41c594abSRalf Baechle return 1; 303*41c594abSRalf Baechle } 304*41c594abSRalf Baechle __setup("ndflush=", ndflush); 305*41c594abSRalf Baechle #ifdef CONFIG_MIPS_MT_FPAFF 306*41c594abSRalf Baechle static int fpaff_threshold = -1; 307*41c594abSRalf Baechle 308*41c594abSRalf Baechle static int __init fpaff_thresh(char *str) 309*41c594abSRalf Baechle { 310*41c594abSRalf Baechle get_option(&str, &fpaff_threshold); 311*41c594abSRalf Baechle return 1; 312*41c594abSRalf Baechle } 313*41c594abSRalf Baechle 314*41c594abSRalf Baechle __setup("fpaff=", fpaff_thresh); 315*41c594abSRalf Baechle #endif /* CONFIG_MIPS_MT_FPAFF */ 316*41c594abSRalf Baechle 317*41c594abSRalf Baechle static unsigned int itc_base = 0; 318*41c594abSRalf Baechle 319*41c594abSRalf Baechle static int __init set_itc_base(char *str) 320*41c594abSRalf Baechle { 321*41c594abSRalf Baechle get_option(&str, &itc_base); 322*41c594abSRalf Baechle return 1; 323*41c594abSRalf Baechle } 324*41c594abSRalf Baechle 325*41c594abSRalf Baechle __setup("itcbase=", set_itc_base); 326*41c594abSRalf Baechle 327*41c594abSRalf Baechle void mips_mt_set_cpuoptions(void) 328*41c594abSRalf Baechle { 329*41c594abSRalf Baechle unsigned int oconfig7 = read_c0_config7(); 330*41c594abSRalf Baechle unsigned int nconfig7 = oconfig7; 331*41c594abSRalf Baechle 332*41c594abSRalf Baechle if (mt_opt_norps) { 333*41c594abSRalf Baechle printk("\"norps\" option deprectated: use \"rpsctl=\"\n"); 334*41c594abSRalf Baechle } 335*41c594abSRalf Baechle if (mt_opt_rpsctl >= 0) { 336*41c594abSRalf Baechle printk("34K return prediction stack override set to %d.\n", 337*41c594abSRalf Baechle mt_opt_rpsctl); 338*41c594abSRalf Baechle if (mt_opt_rpsctl) 339*41c594abSRalf Baechle nconfig7 |= (1 << 2); 340*41c594abSRalf Baechle else 341*41c594abSRalf Baechle nconfig7 &= ~(1 << 2); 342*41c594abSRalf Baechle } 343*41c594abSRalf Baechle if (mt_opt_nblsu >= 0) { 344*41c594abSRalf Baechle printk("34K ALU/LSU sync override set to %d.\n", mt_opt_nblsu); 345*41c594abSRalf Baechle if (mt_opt_nblsu) 346*41c594abSRalf Baechle nconfig7 |= (1 << 5); 347*41c594abSRalf Baechle else 348*41c594abSRalf Baechle nconfig7 &= ~(1 << 5); 349*41c594abSRalf Baechle } 350*41c594abSRalf Baechle if (mt_opt_forceconfig7) { 351*41c594abSRalf Baechle printk("CP0.Config7 forced to 0x%08x.\n", mt_opt_config7); 352*41c594abSRalf Baechle nconfig7 = mt_opt_config7; 353*41c594abSRalf Baechle } 354*41c594abSRalf Baechle if (oconfig7 != nconfig7) { 355*41c594abSRalf Baechle __asm__ __volatile("sync"); 356*41c594abSRalf Baechle write_c0_config7(nconfig7); 357*41c594abSRalf Baechle ehb (); 358*41c594abSRalf Baechle printk("Config7: 0x%08x\n", read_c0_config7()); 359*41c594abSRalf Baechle } 360*41c594abSRalf Baechle 361*41c594abSRalf Baechle /* Report Cache management debug options */ 362*41c594abSRalf Baechle if (mt_protiflush) 363*41c594abSRalf Baechle printk("I-cache flushes single-threaded\n"); 364*41c594abSRalf Baechle if (mt_protdflush) 365*41c594abSRalf Baechle printk("D-cache flushes single-threaded\n"); 366*41c594abSRalf Baechle if (mt_n_iflushes != 1) 367*41c594abSRalf Baechle printk("I-Cache Flushes Repeated %d times\n", mt_n_iflushes); 368*41c594abSRalf Baechle if (mt_n_dflushes != 1) 369*41c594abSRalf Baechle printk("D-Cache Flushes Repeated %d times\n", mt_n_dflushes); 370*41c594abSRalf Baechle 371*41c594abSRalf Baechle #ifdef CONFIG_MIPS_MT_FPAFF 372*41c594abSRalf Baechle /* FPU Use Factor empirically derived from experiments on 34K */ 373*41c594abSRalf Baechle #define FPUSEFACTOR 333 374*41c594abSRalf Baechle 375*41c594abSRalf Baechle if (fpaff_threshold >= 0) { 376*41c594abSRalf Baechle mt_fpemul_threshold = fpaff_threshold; 377*41c594abSRalf Baechle } else { 378*41c594abSRalf Baechle mt_fpemul_threshold = 379*41c594abSRalf Baechle (FPUSEFACTOR * (loops_per_jiffy/(500000/HZ))) / HZ; 380*41c594abSRalf Baechle } 381*41c594abSRalf Baechle printk("FPU Affinity set after %ld emulations\n", 382*41c594abSRalf Baechle mt_fpemul_threshold); 383*41c594abSRalf Baechle #endif /* CONFIG_MIPS_MT_FPAFF */ 384*41c594abSRalf Baechle 385*41c594abSRalf Baechle if (itc_base != 0) { 386*41c594abSRalf Baechle /* 387*41c594abSRalf Baechle * Configure ITC mapping. This code is very 388*41c594abSRalf Baechle * specific to the 34K core family, which uses 389*41c594abSRalf Baechle * a special mode bit ("ITC") in the ErrCtl 390*41c594abSRalf Baechle * register to enable access to ITC control 391*41c594abSRalf Baechle * registers via cache "tag" operations. 392*41c594abSRalf Baechle */ 393*41c594abSRalf Baechle unsigned long ectlval; 394*41c594abSRalf Baechle unsigned long itcblkgrn; 395*41c594abSRalf Baechle 396*41c594abSRalf Baechle /* ErrCtl register is known as "ecc" to Linux */ 397*41c594abSRalf Baechle ectlval = read_c0_ecc(); 398*41c594abSRalf Baechle write_c0_ecc(ectlval | (0x1 << 26)); 399*41c594abSRalf Baechle ehb(); 400*41c594abSRalf Baechle #define INDEX_0 (0x80000000) 401*41c594abSRalf Baechle #define INDEX_8 (0x80000008) 402*41c594abSRalf Baechle /* Read "cache tag" for Dcache pseudo-index 8 */ 403*41c594abSRalf Baechle cache_op(Index_Load_Tag_D, INDEX_8); 404*41c594abSRalf Baechle ehb(); 405*41c594abSRalf Baechle itcblkgrn = read_c0_dtaglo(); 406*41c594abSRalf Baechle itcblkgrn &= 0xfffe0000; 407*41c594abSRalf Baechle /* Set for 128 byte pitch of ITC cells */ 408*41c594abSRalf Baechle itcblkgrn |= 0x00000c00; 409*41c594abSRalf Baechle /* Stage in Tag register */ 410*41c594abSRalf Baechle write_c0_dtaglo(itcblkgrn); 411*41c594abSRalf Baechle ehb(); 412*41c594abSRalf Baechle /* Write out to ITU with CACHE op */ 413*41c594abSRalf Baechle cache_op(Index_Store_Tag_D, INDEX_8); 414*41c594abSRalf Baechle /* Now set base address, and turn ITC on with 0x1 bit */ 415*41c594abSRalf Baechle write_c0_dtaglo((itc_base & 0xfffffc00) | 0x1 ); 416*41c594abSRalf Baechle ehb(); 417*41c594abSRalf Baechle /* Write out to ITU with CACHE op */ 418*41c594abSRalf Baechle cache_op(Index_Store_Tag_D, INDEX_0); 419*41c594abSRalf Baechle write_c0_ecc(ectlval); 420*41c594abSRalf Baechle ehb(); 421*41c594abSRalf Baechle printk("Mapped %ld ITC cells starting at 0x%08x\n", 422*41c594abSRalf Baechle ((itcblkgrn & 0x7fe00000) >> 20), itc_base); 423*41c594abSRalf Baechle } 424*41c594abSRalf Baechle } 425*41c594abSRalf Baechle 426*41c594abSRalf Baechle /* 427*41c594abSRalf Baechle * Function to protect cache flushes from concurrent execution 428*41c594abSRalf Baechle * depends on MP software model chosen. 429*41c594abSRalf Baechle */ 430*41c594abSRalf Baechle 431*41c594abSRalf Baechle void mt_cflush_lockdown(void) 432*41c594abSRalf Baechle { 433*41c594abSRalf Baechle #ifdef CONFIG_MIPS_MT_SMTC 434*41c594abSRalf Baechle void smtc_cflush_lockdown(void); 435*41c594abSRalf Baechle 436*41c594abSRalf Baechle smtc_cflush_lockdown(); 437*41c594abSRalf Baechle #endif /* CONFIG_MIPS_MT_SMTC */ 438*41c594abSRalf Baechle /* FILL IN VSMP and AP/SP VERSIONS HERE */ 439*41c594abSRalf Baechle } 440*41c594abSRalf Baechle 441*41c594abSRalf Baechle void mt_cflush_release(void) 442*41c594abSRalf Baechle { 443*41c594abSRalf Baechle #ifdef CONFIG_MIPS_MT_SMTC 444*41c594abSRalf Baechle void smtc_cflush_release(void); 445*41c594abSRalf Baechle 446*41c594abSRalf Baechle smtc_cflush_release(); 447*41c594abSRalf Baechle #endif /* CONFIG_MIPS_MT_SMTC */ 448*41c594abSRalf Baechle /* FILL IN VSMP and AP/SP VERSIONS HERE */ 449*41c594abSRalf Baechle } 450