Loading arch/mips/include/asm/mipsmtregs.h +13 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,9 @@ #define read_c0_vpeconf0() __read_32bit_c0_register($1, 2) #define write_c0_vpeconf0(val) __write_32bit_c0_register($1, 2, val) #define read_c0_vpeconf1() __read_32bit_c0_register($1, 3) #define write_c0_vpeconf1(val) __write_32bit_c0_register($1, 3, val) #define read_c0_tcstatus() __read_32bit_c0_register($2, 1) #define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val) Loading Loading @@ -124,6 +127,14 @@ #define VPECONF0_XTC_SHIFT 21 #define VPECONF0_XTC (_ULCAST_(0xff) << VPECONF0_XTC_SHIFT) /* VPEConf1 fields (per VPE) */ #define VPECONF1_NCP1_SHIFT 0 #define VPECONF1_NCP1 (_ULCAST_(0xff) << VPECONF1_NCP1_SHIFT) #define VPECONF1_NCP2_SHIFT 10 #define VPECONF1_NCP2 (_ULCAST_(0xff) << VPECONF1_NCP2_SHIFT) #define VPECONF1_NCX_SHIFT 20 #define VPECONF1_NCX (_ULCAST_(0xff) << VPECONF1_NCX_SHIFT) /* TCStatus fields (per TC) */ #define TCSTATUS_TASID (_ULCAST_(0xff)) #define TCSTATUS_IXMT_SHIFT 10 Loading Loading @@ -350,6 +361,8 @@ do { \ #define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val) #define read_vpe_c0_vpeconf0() mftc0(1, 2) #define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val) #define read_vpe_c0_vpeconf1() mftc0(1, 3) #define write_vpe_c0_vpeconf1(val) mttc0(1, 3, val) #define read_vpe_c0_count() mftc0(9, 0) #define write_vpe_c0_count(val) mttc0(9, 0, val) #define read_vpe_c0_status() mftc0(12, 0) Loading arch/mips/include/asm/smtc.h +6 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,12 @@ typedef long asiduse; #endif #endif /* * VPE Management information */ #define MAX_SMTC_VPES MAX_SMTC_TLBS /* FIXME: May not always be true. */ extern asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; struct mm_struct; Loading arch/mips/kernel/smp.c +3 −1 Original line number Diff line number Diff line Loading @@ -102,7 +102,9 @@ asmlinkage __cpuinit void start_secondary(void) #ifdef CONFIG_MIPS_MT_SMTC /* Only do cpu_probe for first TC of CPU */ if ((read_c0_tcbind() & TCBIND_CURTC) == 0) if ((read_c0_tcbind() & TCBIND_CURTC) != 0) __cpu_name[smp_processor_id()] = __cpu_name[0]; else #endif /* CONFIG_MIPS_MT_SMTC */ cpu_probe(); cpu_report(); Loading arch/mips/kernel/smtc.c +68 −8 Original line number Diff line number Diff line Loading @@ -86,6 +86,13 @@ struct smtc_ipi_q IPIQ[NR_CPUS]; static struct smtc_ipi_q freeIPIq; /* * Number of FPU contexts for each VPE */ static int smtc_nconf1[MAX_SMTC_VPES]; /* Forward declarations */ void ipi_decode(struct smtc_ipi *); Loading Loading @@ -174,9 +181,9 @@ static int __init tintq(char *str) __setup("tintq=", tintq); static int imstuckcount[2][8]; static int imstuckcount[MAX_SMTC_VPES][8]; /* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */ static int vpemask[2][8] = { static int vpemask[MAX_SMTC_VPES][8] = { {0, 0, 1, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0, 0, 0, 1} }; Loading Loading @@ -331,6 +338,22 @@ int __init smtc_build_cpu_map(int start_cpu_slot) static void smtc_tc_setup(int vpe, int tc, int cpu) { static int cp1contexts[MAX_SMTC_VPES]; /* * Make a local copy of the available FPU contexts in order * to keep track of TCs that can have one. */ if (tc == 1) { /* * FIXME: Multi-core SMTC hasn't been tested and the * maximum number of VPEs may change. */ cp1contexts[0] = smtc_nconf1[0] - 1; cp1contexts[1] = smtc_nconf1[1]; } settc(tc); write_tc_c0_tchalt(TCHALT_H); mips_ihb(); Loading @@ -343,22 +366,29 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) * an active IPI queue. */ write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); /* Bind tc to vpe */ /* Bind TC to VPE. */ write_tc_c0_tcbind(vpe); /* In general, all TCs should have the same cpu_data indications. */ memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */ if (cpu_data[0].cputype == CPU_34K || cpu_data[0].cputype == CPU_1004K) /* Check to see if there is a FPU context available for this TC. */ if (!cp1contexts[vpe]) cpu_data[cpu].options &= ~MIPS_CPU_FPU; else cp1contexts[vpe]--; /* Store the TC and VPE into the cpu_data structure. */ cpu_data[cpu].vpe_id = vpe; cpu_data[cpu].tc_id = tc; /* Multi-core SMTC hasn't been tested, but be prepared */ /* FIXME: Multi-core SMTC hasn't been tested, but be prepared. */ cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff; } /* * Tweak to get Count registes in as close a sync as possible. The * Tweak to get Count registers synced as closely as possible. The * value seems good for 34K-class cores. */ Loading Loading @@ -466,6 +496,24 @@ void smtc_prepare_cpus(int cpus) smtc_configure_tlb(); for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) { /* Get number of CP1 contexts for each VPE. */ if (tc == 0) { /* * Do not call settc() for TC0 or the FPU context * value will be incorrect. Besides, we know that * we are TC0 anyway. */ smtc_nconf1[0] = ((read_vpe_c0_vpeconf1() & VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT); if (nvpe == 2) { settc(1); smtc_nconf1[1] = ((read_vpe_c0_vpeconf1() & VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT); settc(0); } } if (tcpervpe[vpe] == 0) continue; if (vpe != 0) Loading @@ -479,6 +527,18 @@ void smtc_prepare_cpus(int cpus) */ if (tc != 0) { smtc_tc_setup(vpe, tc, cpu); if (vpe != 0) { /* * Set MVP bit (possibly again). Do it * here to catch CPUs that have no TCs * bound to the VPE at reset. In that * case, a TC must be bound to the VPE * before we can set VPEControl[MVP] */ write_vpe_c0_vpeconf0( read_vpe_c0_vpeconf0() | VPECONF0_MVP); } cpu++; } printk(" %d", tc); Loading Loading
arch/mips/include/asm/mipsmtregs.h +13 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,9 @@ #define read_c0_vpeconf0() __read_32bit_c0_register($1, 2) #define write_c0_vpeconf0(val) __write_32bit_c0_register($1, 2, val) #define read_c0_vpeconf1() __read_32bit_c0_register($1, 3) #define write_c0_vpeconf1(val) __write_32bit_c0_register($1, 3, val) #define read_c0_tcstatus() __read_32bit_c0_register($2, 1) #define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val) Loading Loading @@ -124,6 +127,14 @@ #define VPECONF0_XTC_SHIFT 21 #define VPECONF0_XTC (_ULCAST_(0xff) << VPECONF0_XTC_SHIFT) /* VPEConf1 fields (per VPE) */ #define VPECONF1_NCP1_SHIFT 0 #define VPECONF1_NCP1 (_ULCAST_(0xff) << VPECONF1_NCP1_SHIFT) #define VPECONF1_NCP2_SHIFT 10 #define VPECONF1_NCP2 (_ULCAST_(0xff) << VPECONF1_NCP2_SHIFT) #define VPECONF1_NCX_SHIFT 20 #define VPECONF1_NCX (_ULCAST_(0xff) << VPECONF1_NCX_SHIFT) /* TCStatus fields (per TC) */ #define TCSTATUS_TASID (_ULCAST_(0xff)) #define TCSTATUS_IXMT_SHIFT 10 Loading Loading @@ -350,6 +361,8 @@ do { \ #define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val) #define read_vpe_c0_vpeconf0() mftc0(1, 2) #define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val) #define read_vpe_c0_vpeconf1() mftc0(1, 3) #define write_vpe_c0_vpeconf1(val) mttc0(1, 3, val) #define read_vpe_c0_count() mftc0(9, 0) #define write_vpe_c0_count(val) mttc0(9, 0, val) #define read_vpe_c0_status() mftc0(12, 0) Loading
arch/mips/include/asm/smtc.h +6 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,12 @@ typedef long asiduse; #endif #endif /* * VPE Management information */ #define MAX_SMTC_VPES MAX_SMTC_TLBS /* FIXME: May not always be true. */ extern asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; struct mm_struct; Loading
arch/mips/kernel/smp.c +3 −1 Original line number Diff line number Diff line Loading @@ -102,7 +102,9 @@ asmlinkage __cpuinit void start_secondary(void) #ifdef CONFIG_MIPS_MT_SMTC /* Only do cpu_probe for first TC of CPU */ if ((read_c0_tcbind() & TCBIND_CURTC) == 0) if ((read_c0_tcbind() & TCBIND_CURTC) != 0) __cpu_name[smp_processor_id()] = __cpu_name[0]; else #endif /* CONFIG_MIPS_MT_SMTC */ cpu_probe(); cpu_report(); Loading
arch/mips/kernel/smtc.c +68 −8 Original line number Diff line number Diff line Loading @@ -86,6 +86,13 @@ struct smtc_ipi_q IPIQ[NR_CPUS]; static struct smtc_ipi_q freeIPIq; /* * Number of FPU contexts for each VPE */ static int smtc_nconf1[MAX_SMTC_VPES]; /* Forward declarations */ void ipi_decode(struct smtc_ipi *); Loading Loading @@ -174,9 +181,9 @@ static int __init tintq(char *str) __setup("tintq=", tintq); static int imstuckcount[2][8]; static int imstuckcount[MAX_SMTC_VPES][8]; /* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */ static int vpemask[2][8] = { static int vpemask[MAX_SMTC_VPES][8] = { {0, 0, 1, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0, 0, 0, 1} }; Loading Loading @@ -331,6 +338,22 @@ int __init smtc_build_cpu_map(int start_cpu_slot) static void smtc_tc_setup(int vpe, int tc, int cpu) { static int cp1contexts[MAX_SMTC_VPES]; /* * Make a local copy of the available FPU contexts in order * to keep track of TCs that can have one. */ if (tc == 1) { /* * FIXME: Multi-core SMTC hasn't been tested and the * maximum number of VPEs may change. */ cp1contexts[0] = smtc_nconf1[0] - 1; cp1contexts[1] = smtc_nconf1[1]; } settc(tc); write_tc_c0_tchalt(TCHALT_H); mips_ihb(); Loading @@ -343,22 +366,29 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) * an active IPI queue. */ write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); /* Bind tc to vpe */ /* Bind TC to VPE. */ write_tc_c0_tcbind(vpe); /* In general, all TCs should have the same cpu_data indications. */ memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */ if (cpu_data[0].cputype == CPU_34K || cpu_data[0].cputype == CPU_1004K) /* Check to see if there is a FPU context available for this TC. */ if (!cp1contexts[vpe]) cpu_data[cpu].options &= ~MIPS_CPU_FPU; else cp1contexts[vpe]--; /* Store the TC and VPE into the cpu_data structure. */ cpu_data[cpu].vpe_id = vpe; cpu_data[cpu].tc_id = tc; /* Multi-core SMTC hasn't been tested, but be prepared */ /* FIXME: Multi-core SMTC hasn't been tested, but be prepared. */ cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff; } /* * Tweak to get Count registes in as close a sync as possible. The * Tweak to get Count registers synced as closely as possible. The * value seems good for 34K-class cores. */ Loading Loading @@ -466,6 +496,24 @@ void smtc_prepare_cpus(int cpus) smtc_configure_tlb(); for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) { /* Get number of CP1 contexts for each VPE. */ if (tc == 0) { /* * Do not call settc() for TC0 or the FPU context * value will be incorrect. Besides, we know that * we are TC0 anyway. */ smtc_nconf1[0] = ((read_vpe_c0_vpeconf1() & VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT); if (nvpe == 2) { settc(1); smtc_nconf1[1] = ((read_vpe_c0_vpeconf1() & VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT); settc(0); } } if (tcpervpe[vpe] == 0) continue; if (vpe != 0) Loading @@ -479,6 +527,18 @@ void smtc_prepare_cpus(int cpus) */ if (tc != 0) { smtc_tc_setup(vpe, tc, cpu); if (vpe != 0) { /* * Set MVP bit (possibly again). Do it * here to catch CPUs that have no TCs * bound to the VPE at reset. In that * case, a TC must be bound to the VPE * before we can set VPEControl[MVP] */ write_vpe_c0_vpeconf0( read_vpe_c0_vpeconf0() | VPECONF0_MVP); } cpu++; } printk(" %d", tc); Loading