* [PATCH 1/4] MIPS: Allow platform specific scratch registers
2013-06-10 7:35 [PATCH v3 0/4]Use scratch registers on XLR/XLS/XLP Jayachandran C
@ 2013-06-10 7:35 ` Jayachandran C
2013-06-10 7:35 ` [PATCH 2/4] MIPS: Fixup check for invalid scratch register Jayachandran C
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Jayachandran C @ 2013-06-10 7:35 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
XLR/XLP COP0 scratch is register 22, sel 0-7. Add a function
kscratch_reg() which returns the scratch register for the platform,
and use the return value while generating TLB handlers.
Setup kscratch_mask to 0xf for XLR/XLP since the config4 register
does not exist. This allows the kernel to allocate scratch registers
0-3 if needed.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/kernel/cpu-probe.c | 1 +
arch/mips/mm/tlbex.c | 43 +++++++++++++++++++++++++++---------------
2 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index c6568bf..265c97d 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -959,6 +959,7 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
set_isa(c, MIPS_CPU_ISA_M64R1);
c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
}
+ c->kscratch_mask = 0xf;
}
#ifdef CONFIG_64BIT
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index ce9818e..b687c59 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -309,6 +309,17 @@ static int check_for_high_segbits __cpuinitdata;
static unsigned int kscratch_used_mask __cpuinitdata;
+static inline int __maybe_unused kscratch_reg(void)
+{
+ switch (current_cpu_type()) {
+ case CPU_XLP:
+ case CPU_XLR:
+ return 22;
+ default:
+ return 31;
+ }
+}
+
static int __cpuinit allocate_kscratch(void)
{
int r;
@@ -326,6 +337,7 @@ static int __cpuinit allocate_kscratch(void)
return r;
}
+static int c0_kscratch __cpuinitdata;
static int scratch_reg __cpuinitdata;
static int pgd_reg __cpuinitdata;
enum vmalloc64_mode {not_refill, refill_scratch, refill_noscratch};
@@ -340,7 +352,7 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p)
if (scratch_reg > 0) {
/* Save in CPU local C0_KScratch? */
- UASM_i_MTC0(p, 1, 31, scratch_reg);
+ UASM_i_MTC0(p, 1, c0_kscratch, scratch_reg);
r.r1 = K0;
r.r2 = K1;
r.r3 = 1;
@@ -389,7 +401,7 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p)
static void __cpuinit build_restore_work_registers(u32 **p)
{
if (scratch_reg > 0) {
- UASM_i_MFC0(p, 1, 31, scratch_reg);
+ UASM_i_MFC0(p, 1, c0_kscratch, scratch_reg);
return;
}
/* K0 already points to save area, restore $1 and $2 */
@@ -678,7 +690,7 @@ static __cpuinit void build_restore_pagemask(u32 **p,
uasm_il_b(p, r, lid);
}
if (scratch_reg > 0)
- UASM_i_MFC0(p, 1, 31, scratch_reg);
+ UASM_i_MFC0(p, 1, c0_kscratch, scratch_reg);
else
UASM_i_LW(p, 1, scratchpad_offset(0), 0);
} else {
@@ -821,7 +833,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
if (pgd_reg != -1) {
/* pgd is in pgd_reg */
- UASM_i_MFC0(p, ptr, 31, pgd_reg);
+ UASM_i_MFC0(p, ptr, c0_kscratch, pgd_reg);
} else {
/*
* &pgd << 11 stored in CONTEXT [23..63].
@@ -934,7 +946,7 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
if (mode == refill_scratch) {
if (scratch_reg > 0)
- UASM_i_MFC0(p, 1, 31, scratch_reg);
+ UASM_i_MFC0(p, 1, c0_kscratch, scratch_reg);
else
UASM_i_LW(p, 1, scratchpad_offset(0), 0);
} else {
@@ -1100,7 +1112,7 @@ struct mips_huge_tlb_info {
static struct mips_huge_tlb_info __cpuinit
build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
struct uasm_reloc **r, unsigned int tmp,
- unsigned int ptr, int c0_scratch)
+ unsigned int ptr, int c0_scratch_reg)
{
struct mips_huge_tlb_info rv;
unsigned int even, odd;
@@ -1114,12 +1126,12 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
UASM_i_MFC0(p, tmp, C0_BADVADDR);
if (pgd_reg != -1)
- UASM_i_MFC0(p, ptr, 31, pgd_reg);
+ UASM_i_MFC0(p, ptr, c0_kscratch, pgd_reg);
else
UASM_i_MFC0(p, ptr, C0_CONTEXT);
- if (c0_scratch >= 0)
- UASM_i_MTC0(p, scratch, 31, c0_scratch);
+ if (c0_scratch_reg >= 0)
+ UASM_i_MTC0(p, scratch, c0_kscratch, c0_scratch_reg);
else
UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
@@ -1134,14 +1146,14 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
}
} else {
if (pgd_reg != -1)
- UASM_i_MFC0(p, ptr, 31, pgd_reg);
+ UASM_i_MFC0(p, ptr, c0_kscratch, pgd_reg);
else
UASM_i_MFC0(p, ptr, C0_CONTEXT);
UASM_i_MFC0(p, tmp, C0_BADVADDR);
- if (c0_scratch >= 0)
- UASM_i_MTC0(p, scratch, 31, c0_scratch);
+ if (c0_scratch_reg >= 0)
+ UASM_i_MTC0(p, scratch, c0_kscratch, c0_scratch_reg);
else
UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
@@ -1246,8 +1258,8 @@ build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
}
UASM_i_MTC0(p, odd, C0_ENTRYLO1); /* load it */
- if (c0_scratch >= 0) {
- UASM_i_MFC0(p, scratch, 31, c0_scratch);
+ if (c0_scratch_reg >= 0) {
+ UASM_i_MFC0(p, scratch, c0_kscratch, c0_scratch_reg);
build_tlb_write_entry(p, l, r, tlb_random);
uasm_l_leave(l, *p);
rv.restore_scratch = 1;
@@ -1494,7 +1506,7 @@ static void __cpuinit build_r4000_setup_pgd(void)
} else {
/* PGD in c0_KScratch */
uasm_i_jr(&p, 31);
- UASM_i_MTC0(&p, a0, 31, pgd_reg);
+ UASM_i_MTC0(&p, a0, c0_kscratch, pgd_reg);
}
if (p - tlbmiss_handler_setup_pgd_array > ARRAY_SIZE(tlbmiss_handler_setup_pgd_array))
panic("tlbmiss_handler_setup_pgd_array space exceeded");
@@ -2209,6 +2221,7 @@ void __cpuinit build_tlb_refill_handler(void)
default:
if (!run_once) {
+ c0_kscratch = kscratch_reg();
scratch_reg = allocate_kscratch();
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
build_r4000_setup_pgd();
--
1.7.9.5
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/4] MIPS: Fixup check for invalid scratch register
2013-06-10 7:35 [PATCH v3 0/4]Use scratch registers on XLR/XLS/XLP Jayachandran C
2013-06-10 7:35 ` [PATCH 1/4] MIPS: Allow platform specific scratch registers Jayachandran C
@ 2013-06-10 7:35 ` Jayachandran C
2013-06-10 7:35 ` [PATCH 3/4] MIPS: mm: Use scratch for PGD when !CONFIG_MIPS_PGD_C0_CONTEXT Jayachandran C
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Jayachandran C @ 2013-06-10 7:35 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
The invalid value for scratch register is -1, so update the checks of
the form (scratch_reg > 0) to be (scratch_reg >= 0). This will fix
the case in Netlogic XLP where the scratch_reg can be 0.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/mm/tlbex.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index b687c59..6bac544 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -350,7 +350,7 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p)
int smp_processor_id_sel;
int smp_processor_id_shift;
- if (scratch_reg > 0) {
+ if (scratch_reg >= 0) {
/* Save in CPU local C0_KScratch? */
UASM_i_MTC0(p, 1, c0_kscratch, scratch_reg);
r.r1 = K0;
@@ -400,7 +400,7 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p)
static void __cpuinit build_restore_work_registers(u32 **p)
{
- if (scratch_reg > 0) {
+ if (scratch_reg >= 0) {
UASM_i_MFC0(p, 1, c0_kscratch, scratch_reg);
return;
}
@@ -689,7 +689,7 @@ static __cpuinit void build_restore_pagemask(u32 **p,
uasm_i_mtc0(p, 0, C0_PAGEMASK);
uasm_il_b(p, r, lid);
}
- if (scratch_reg > 0)
+ if (scratch_reg >= 0)
UASM_i_MFC0(p, 1, c0_kscratch, scratch_reg);
else
UASM_i_LW(p, 1, scratchpad_offset(0), 0);
@@ -945,7 +945,7 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
uasm_i_jr(p, ptr);
if (mode == refill_scratch) {
- if (scratch_reg > 0)
+ if (scratch_reg >= 0)
UASM_i_MFC0(p, 1, c0_kscratch, scratch_reg);
else
UASM_i_LW(p, 1, scratchpad_offset(0), 0);
@@ -1302,7 +1302,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
memset(relocs, 0, sizeof(relocs));
memset(final_handler, 0, sizeof(final_handler));
- if ((scratch_reg > 0 || scratchpad_available()) && use_bbit_insns()) {
+ if ((scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) {
htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1,
scratch_reg);
vmalloc_mode = refill_scratch;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 3/4] MIPS: mm: Use scratch for PGD when !CONFIG_MIPS_PGD_C0_CONTEXT
2013-06-10 7:35 [PATCH v3 0/4]Use scratch registers on XLR/XLS/XLP Jayachandran C
2013-06-10 7:35 ` [PATCH 1/4] MIPS: Allow platform specific scratch registers Jayachandran C
2013-06-10 7:35 ` [PATCH 2/4] MIPS: Fixup check for invalid scratch register Jayachandran C
@ 2013-06-10 7:35 ` Jayachandran C
2013-06-10 7:35 ` [PATCH 4/4] MIPS: Move definition of SMP processor id register to header file Jayachandran C
2013-06-11 11:44 ` [PATCH v3 0/4]Use scratch registers on XLR/XLS/XLP Jayachandran C.
4 siblings, 0 replies; 6+ messages in thread
From: Jayachandran C @ 2013-06-10 7:35 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
Allow usage of scratch register for current pgd even when
MIPS_PGD_C0_CONTEXT is not configured. MIPS_PGD_C0_CONTEXT is set
for 64r2 platforms to indicate availability of Xcontext for saving
cpuid, and this was also tied to using scratch registers for PGD.
This commit will allow usage of scratch register to store the current
pgd, if one can be allocated for the platform, even in other cases
(i.e when MIPS_PGD_C0_CONTEXT is not set). The processor id will be
kept in the CP0 Context register in this case.
The code to store the current pgd for the TLB miss handler is now
generated in all cases, and if scratch register is available, the
pgd is also stored in the scratch register.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/include/asm/mmu_context.h | 6 +-
arch/mips/mm/tlbex.c | 143 ++++++++++++++++++++++-------------
2 files changed, 92 insertions(+), 57 deletions(-)
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h
index 8201160..41aa181 100644
--- a/arch/mips/include/asm/mmu_context.h
+++ b/arch/mips/include/asm/mmu_context.h
@@ -24,8 +24,6 @@
#endif /* SMTC */
#include <asm-generic/mm_hooks.h>
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
-
#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
do { \
void (*tlbmiss_handler_setup_pgd)(unsigned long); \
@@ -36,6 +34,7 @@ do { \
tlbmiss_handler_setup_pgd((unsigned long)(pgd)); \
} while (0)
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
#define TLBMISS_HANDLER_SETUP() \
do { \
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir); \
@@ -51,9 +50,6 @@ do { \
*/
extern unsigned long pgd_current[];
-#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
- pgd_current[smp_processor_id()] = (unsigned long)(pgd)
-
#ifdef CONFIG_32BIT
#define TLBMISS_HANDLER_SETUP() \
write_c0_context((unsigned long) smp_processor_id() << 25); \
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 6bac544..e1aadda 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -830,11 +830,11 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
}
/* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
if (pgd_reg != -1) {
/* pgd is in pgd_reg */
UASM_i_MFC0(p, ptr, c0_kscratch, pgd_reg);
} else {
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
/*
* &pgd << 11 stored in CONTEXT [23..63].
*/
@@ -846,30 +846,32 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
/* 1 0 1 0 1 << 6 xkphys cached */
uasm_i_ori(p, ptr, ptr, 0x540);
uasm_i_drotr(p, ptr, ptr, 11);
- }
-#elif defined(CONFIG_SMP)
-# ifdef CONFIG_MIPS_MT_SMTC
- /*
- * SMTC uses TCBind value as "CPU" index
- */
- uasm_i_mfc0(p, ptr, C0_TCBIND);
- uasm_i_dsrl_safe(p, ptr, ptr, 19);
+#else
+#if defined(CONFIG_SMP)
+# ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC uses TCBind value as "CPU" index
+ */
+ uasm_i_mfc0(p, ptr, C0_TCBIND);
+ uasm_i_dsrl_safe(p, ptr, ptr, 19);
# else
- /*
- * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
- * stored in CONTEXT.
- */
- uasm_i_dmfc0(p, ptr, C0_CONTEXT);
- uasm_i_dsrl_safe(p, ptr, ptr, 23);
+ /*
+ * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
+ * stored in CONTEXT.
+ */
+ uasm_i_dmfc0(p, ptr, C0_CONTEXT);
+ uasm_i_dsrl_safe(p, ptr, ptr, 23);
# endif
- UASM_i_LA_mostly(p, tmp, pgdc);
- uasm_i_daddu(p, ptr, ptr, tmp);
- uasm_i_dmfc0(p, tmp, C0_BADVADDR);
- uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
+ UASM_i_LA_mostly(p, tmp, pgdc);
+ uasm_i_daddu(p, ptr, ptr, tmp);
+ uasm_i_dmfc0(p, tmp, C0_BADVADDR);
+ uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
#else
- UASM_i_LA_mostly(p, ptr, pgdc);
- uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
-#endif
+ UASM_i_LA_mostly(p, ptr, pgdc);
+ uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
+#endif /* SMP */
+#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
+ }
uasm_l_vmalloc_done(l, *p);
@@ -964,31 +966,37 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
static void __cpuinit __maybe_unused
build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
{
- long pgdc = (long)pgd_current;
+ if (pgd_reg != -1) {
+ /* pgd is in pgd_reg */
+ uasm_i_mfc0(p, ptr, c0_kscratch, pgd_reg);
+ uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+ } else {
+ long pgdc = (long)pgd_current;
- /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */
+ /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */
#ifdef CONFIG_SMP
#ifdef CONFIG_MIPS_MT_SMTC
- /*
- * SMTC uses TCBind value as "CPU" index
- */
- uasm_i_mfc0(p, ptr, C0_TCBIND);
- UASM_i_LA_mostly(p, tmp, pgdc);
- uasm_i_srl(p, ptr, ptr, 19);
+ /*
+ * SMTC uses TCBind value as "CPU" index
+ */
+ uasm_i_mfc0(p, ptr, C0_TCBIND);
+ UASM_i_LA_mostly(p, tmp, pgdc);
+ uasm_i_srl(p, ptr, ptr, 19);
#else
- /*
- * smp_processor_id() << 3 is stored in CONTEXT.
- */
- uasm_i_mfc0(p, ptr, C0_CONTEXT);
- UASM_i_LA_mostly(p, tmp, pgdc);
- uasm_i_srl(p, ptr, ptr, 23);
+ /*
+ * smp_processor_id() << 3 is stored in CONTEXT.
+ */
+ uasm_i_mfc0(p, ptr, C0_CONTEXT);
+ UASM_i_LA_mostly(p, tmp, pgdc);
+ uasm_i_srl(p, ptr, ptr, 23);
#endif
- uasm_i_addu(p, ptr, tmp, ptr);
+ uasm_i_addu(p, ptr, tmp, ptr);
#else
- UASM_i_LA_mostly(p, ptr, pgdc);
+ UASM_i_LA_mostly(p, ptr, pgdc);
#endif
- uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
- uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr);
+ uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+ uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr);
+ }
uasm_i_srl(p, tmp, tmp, PGDIR_SHIFT); /* get pgd only bits */
uasm_i_sll(p, tmp, tmp, PGD_T_LOG2);
uasm_i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
@@ -1469,16 +1477,17 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
u32 handle_tlbl[FASTPATH_SIZE] __cacheline_aligned;
u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned;
u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned;
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
u32 tlbmiss_handler_setup_pgd_array[16] __cacheline_aligned;
-static void __cpuinit build_r4000_setup_pgd(void)
+static void __cpuinit build_setup_pgd(void)
{
const int a0 = 4;
- const int a1 = 5;
+ const int __maybe_unused a1 = 5;
+ const int a2 = 6;
u32 *p = tlbmiss_handler_setup_pgd_array;
- struct uasm_label *l = labels;
- struct uasm_reloc *r = relocs;
+#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+ long pgdc = (long)pgd_current;
+#endif
memset(tlbmiss_handler_setup_pgd_array, 0, sizeof(tlbmiss_handler_setup_pgd_array));
memset(labels, 0, sizeof(labels));
@@ -1486,7 +1495,11 @@ static void __cpuinit build_r4000_setup_pgd(void)
pgd_reg = allocate_kscratch();
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
if (pgd_reg == -1) {
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+
/* PGD << 11 in c0_Context */
/*
* If it is a ckseg0 address, convert to a physical
@@ -1508,8 +1521,38 @@ static void __cpuinit build_r4000_setup_pgd(void)
uasm_i_jr(&p, 31);
UASM_i_MTC0(&p, a0, c0_kscratch, pgd_reg);
}
+#else
+#if defined(CONFIG_SMP)
+# ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC uses TCBind value as "CPU" index
+ */
+ uasm_i_mfc0(&p, a1, C0_TCBIND);
+ uasm_i_dsrl_safe(&p, a1, a1, 19);
+# else
+ /*
+ * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
+ * stored in CONTEXT.
+ */
+ UASM_i_MFC0(&p, a1, C0_CONTEXT);
+ uasm_i_dsrl_safe(&p, a1, a1, 23);
+# endif
+ UASM_i_LA_mostly(&p, a2, pgdc);
+ UASM_i_ADDU(&p, a2, a2, a1);
+ UASM_i_SW(&p, a0, uasm_rel_lo(pgdc), a2);
+#else
+ UASM_i_LA_mostly(&p, a2, pgdc);
+ UASM_i_SW(&p, a0, uasm_rel_lo(pgdc), a2);
+#endif /* SMP */
+ uasm_i_jr(&p, 31);
+ if (pgd_reg != -1) {
+ /* PGD also in c0_KScratch */
+ UASM_i_MTC0(&p, a0, c0_kscratch, pgd_reg);
+ } else
+ uasm_i_nop(&p);
+#endif
if (p - tlbmiss_handler_setup_pgd_array > ARRAY_SIZE(tlbmiss_handler_setup_pgd_array))
- panic("tlbmiss_handler_setup_pgd_array space exceeded");
+ panic("tlbmiss_handler_setup_pgd space exceeded");
uasm_resolve_relocs(relocs, labels);
pr_debug("Wrote tlbmiss_handler_setup_pgd_array (%u instructions).\n",
(unsigned int)(p - tlbmiss_handler_setup_pgd_array));
@@ -1518,7 +1561,6 @@ static void __cpuinit build_r4000_setup_pgd(void)
tlbmiss_handler_setup_pgd_array,
ARRAY_SIZE(tlbmiss_handler_setup_pgd_array));
}
-#endif
static void __cpuinit
iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
@@ -2200,6 +2242,7 @@ void __cpuinit build_tlb_refill_handler(void)
if (!run_once) {
if (!cpu_has_local_ebase)
build_r3000_tlb_refill_handler();
+ build_setup_pgd();
build_r3000_tlb_load_handler();
build_r3000_tlb_store_handler();
build_r3000_tlb_modify_handler();
@@ -2223,9 +2266,7 @@ void __cpuinit build_tlb_refill_handler(void)
if (!run_once) {
c0_kscratch = kscratch_reg();
scratch_reg = allocate_kscratch();
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
- build_r4000_setup_pgd();
-#endif
+ build_setup_pgd();
build_r4000_tlb_load_handler();
build_r4000_tlb_store_handler();
build_r4000_tlb_modify_handler();
@@ -2246,8 +2287,6 @@ void __cpuinit flush_tlb_handlers(void)
(unsigned long)handle_tlbs + sizeof(handle_tlbs));
local_flush_icache_range((unsigned long)handle_tlbm,
(unsigned long)handle_tlbm + sizeof(handle_tlbm));
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd_array,
(unsigned long)tlbmiss_handler_setup_pgd_array + sizeof(handle_tlbm));
-#endif
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 4/4] MIPS: Move definition of SMP processor id register to header file
2013-06-10 7:35 [PATCH v3 0/4]Use scratch registers on XLR/XLS/XLP Jayachandran C
` (2 preceding siblings ...)
2013-06-10 7:35 ` [PATCH 3/4] MIPS: mm: Use scratch for PGD when !CONFIG_MIPS_PGD_C0_CONTEXT Jayachandran C
@ 2013-06-10 7:35 ` Jayachandran C
2013-06-11 11:44 ` [PATCH v3 0/4]Use scratch registers on XLR/XLS/XLP Jayachandran C.
4 siblings, 0 replies; 6+ messages in thread
From: Jayachandran C @ 2013-06-10 7:35 UTC (permalink / raw)
To: linux-mips, ralf; +Cc: Jayachandran C
The definition of the CP0 register used to save the smp processor
id is repicated in many files, move them all to thread_info.h.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/include/asm/mmu_context.h | 16 +++----
arch/mips/include/asm/stackframe.h | 23 ++++-------
arch/mips/include/asm/thread_info.h | 33 ++++++++++++++-
arch/mips/mm/tlbex.c | 78 +++++++----------------------------
4 files changed, 60 insertions(+), 90 deletions(-)
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h
index 41aa181..8b138cf 100644
--- a/arch/mips/include/asm/mmu_context.h
+++ b/arch/mips/include/asm/mmu_context.h
@@ -38,10 +38,11 @@ do { \
#define TLBMISS_HANDLER_SETUP() \
do { \
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir); \
- write_c0_xcontext((unsigned long) smp_processor_id() << 51); \
+ write_c0_xcontext((unsigned long) smp_processor_id() << \
+ SMP_CPUID_REGSHIFT); \
} while (0)
-#else /* CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/
+#else /* !CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/
/*
* For the fast tlb miss handlers, we keep a per cpu array of pointers
@@ -50,18 +51,11 @@ do { \
*/
extern unsigned long pgd_current[];
-#ifdef CONFIG_32BIT
#define TLBMISS_HANDLER_SETUP() \
- write_c0_context((unsigned long) smp_processor_id() << 25); \
+ write_c0_context((unsigned long) smp_processor_id() << \
+ SMP_CPUID_REGSHIFT); \
back_to_back_c0_hazard(); \
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
-#endif
-#ifdef CONFIG_64BIT
-#define TLBMISS_HANDLER_SETUP() \
- write_c0_context((unsigned long) smp_processor_id() << 26); \
- back_to_back_c0_hazard(); \
- TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
-#endif
#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
index a89d1b1..e9300d4 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -17,6 +17,7 @@
#include <asm/asmmacro.h>
#include <asm/mipsregs.h>
#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
/*
* For SMTC kernel, global IE should be left set, and interrupts
@@ -86,20 +87,12 @@
#ifdef CONFIG_SMP
#ifdef CONFIG_MIPS_MT_SMTC
-#define PTEBASE_SHIFT 19 /* TCBIND */
-#define CPU_ID_REG CP0_TCBIND
-#define CPU_ID_MFC0 mfc0
-#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
-#define PTEBASE_SHIFT 48 /* XCONTEXT */
-#define CPU_ID_REG CP0_XCONTEXT
-#define CPU_ID_MFC0 MFC0
+#define SMP_CPUID_MFC0 mfc0
#else
-#define PTEBASE_SHIFT 23 /* CONTEXT */
-#define CPU_ID_REG CP0_CONTEXT
-#define CPU_ID_MFC0 MFC0
+#define SMP_CPUID_MFC0 MFC0
#endif
.macro get_saved_sp /* SMP variation */
- CPU_ID_MFC0 k0, CPU_ID_REG
+ SMP_CPUID_MFC0 k0, SMP_CPUID_REG
#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
lui k1, %hi(kernelsp)
#else
@@ -109,17 +102,17 @@
daddiu k1, %hi(kernelsp)
dsll k1, 16
#endif
- LONG_SRL k0, PTEBASE_SHIFT
+ LONG_SRL k0, SMP_CPUID_PTRSHIFT
LONG_ADDU k1, k0
LONG_L k1, %lo(kernelsp)(k1)
.endm
.macro set_saved_sp stackp temp temp2
- CPU_ID_MFC0 \temp, CPU_ID_REG
- LONG_SRL \temp, PTEBASE_SHIFT
+ SMP_CPUID_MFC0 \temp, SMP_CPUID_REG
+ LONG_SRL \temp, SMP_CPUID_PTRSHIFT
LONG_S \stackp, kernelsp(\temp)
.endm
-#else
+#else /* !CONFIG_SMP */
.macro get_saved_sp /* Uniprocessor variation */
#ifdef CONFIG_CPU_JUMP_WORKAROUNDS
/*
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index 61215a3..4867447 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -147,6 +147,37 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_ALLWORK_MASK (_TIF_NOHZ | _TIF_WORK_MASK | \
_TIF_WORK_SYSCALL_EXIT)
-#endif /* __KERNEL__ */
+/*
+ * We stash processor id into a COP0 register to retrieve it fast
+ * at kernel exception entry. The register and shift used for this.
+ */
+#ifdef CONFIG_MIPS_MT_SMTC
+#ifdef __ASSEMBLY__
+#define SMP_CPUID_REG $2, 2 /* TCBIND */
+#else
+#define SMP_CPUID_REG 2, 2
+#endif
+#define SMP_CPUID_PTRSHIFT 19
+#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
+#ifdef __ASSEMBLY__
+#define SMP_CPUID_REG $20, 0 /* XCONTEXT */
+#else
+#define SMP_CPUID_REG 20, 0
+#endif
+#define SMP_CPUID_PTRSHIFT 48
+#else
+#ifdef __ASSEMBLY__
+#define SMP_CPUID_REG $4, 0 /* CONTEXT */
+#else
+#define SMP_CPUID_REG 4, 0
+#endif
+#define SMP_CPUID_PTRSHIFT 23
+#endif
+#ifdef CONFIG_64BIT
+#define SMP_CPUID_REGSHIFT (SMP_CPUID_PTRSHIFT + 3)
+#else
+#define SMP_CPUID_REGSHIFT (SMP_CPUID_PTRSHIFT + 2)
+#endif
+#endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index e1aadda..d057641 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -346,10 +346,6 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p)
{
struct work_registers r;
- int smp_processor_id_reg;
- int smp_processor_id_sel;
- int smp_processor_id_shift;
-
if (scratch_reg >= 0) {
/* Save in CPU local C0_KScratch? */
UASM_i_MTC0(p, 1, c0_kscratch, scratch_reg);
@@ -360,25 +356,9 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p)
}
if (num_possible_cpus() > 1) {
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
- smp_processor_id_shift = 51;
- smp_processor_id_reg = 20; /* XContext */
- smp_processor_id_sel = 0;
-#else
-# ifdef CONFIG_32BIT
- smp_processor_id_shift = 25;
- smp_processor_id_reg = 4; /* Context */
- smp_processor_id_sel = 0;
-# endif
-# ifdef CONFIG_64BIT
- smp_processor_id_shift = 26;
- smp_processor_id_reg = 4; /* Context */
- smp_processor_id_sel = 0;
-# endif
-#endif
/* Get smp_processor_id */
- UASM_i_MFC0(p, K0, smp_processor_id_reg, smp_processor_id_sel);
- UASM_i_SRL_SAFE(p, K0, K0, smp_processor_id_shift);
+ UASM_i_MFC0(p, K0, SMP_CPUID_REG);
+ UASM_i_SRL_SAFE(p, K0, K0, SMP_CPUID_REGSHIFT);
/* handler_reg_save index in K0 */
UASM_i_SLL(p, K0, K0, ilog2(sizeof(struct tlb_reg_save)));
@@ -848,20 +828,12 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
uasm_i_drotr(p, ptr, ptr, 11);
#else
#if defined(CONFIG_SMP)
-# ifdef CONFIG_MIPS_MT_SMTC
- /*
- * SMTC uses TCBind value as "CPU" index
- */
- uasm_i_mfc0(p, ptr, C0_TCBIND);
- uasm_i_dsrl_safe(p, ptr, ptr, 19);
-# else
- /*
- * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
- * stored in CONTEXT.
- */
- uasm_i_dmfc0(p, ptr, C0_CONTEXT);
- uasm_i_dsrl_safe(p, ptr, ptr, 23);
-# endif
+#ifdef CONFIG_MIPS_MT_SMTC
+ uasm_i_mfc0(p, ptr, SMP_CPUID_REG);
+#else
+ uasm_i_dmfc0(p, ptr, SMP_CPUID_REG);
+#endif
+ uasm_i_dsrl_safe(p, ptr, ptr, SMP_CPUID_PTRSHIFT);
UASM_i_LA_mostly(p, tmp, pgdc);
uasm_i_daddu(p, ptr, ptr, tmp);
uasm_i_dmfc0(p, tmp, C0_BADVADDR);
@@ -975,21 +947,9 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
/* 32 bit SMP has smp_processor_id() stored in CONTEXT. */
#ifdef CONFIG_SMP
-#ifdef CONFIG_MIPS_MT_SMTC
- /*
- * SMTC uses TCBind value as "CPU" index
- */
- uasm_i_mfc0(p, ptr, C0_TCBIND);
- UASM_i_LA_mostly(p, tmp, pgdc);
- uasm_i_srl(p, ptr, ptr, 19);
-#else
- /*
- * smp_processor_id() << 3 is stored in CONTEXT.
- */
- uasm_i_mfc0(p, ptr, C0_CONTEXT);
+ uasm_i_mfc0(p, ptr, SMP_CPUID_REG);
UASM_i_LA_mostly(p, tmp, pgdc);
- uasm_i_srl(p, ptr, ptr, 23);
-#endif
+ uasm_i_srl(p, ptr, ptr, SMP_CPUID_PTRSHIFT);
uasm_i_addu(p, ptr, tmp, ptr);
#else
UASM_i_LA_mostly(p, ptr, pgdc);
@@ -1524,19 +1484,11 @@ static void __cpuinit build_setup_pgd(void)
#else
#if defined(CONFIG_SMP)
# ifdef CONFIG_MIPS_MT_SMTC
- /*
- * SMTC uses TCBind value as "CPU" index
- */
- uasm_i_mfc0(&p, a1, C0_TCBIND);
- uasm_i_dsrl_safe(&p, a1, a1, 19);
-# else
- /*
- * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
- * stored in CONTEXT.
- */
- UASM_i_MFC0(&p, a1, C0_CONTEXT);
- uasm_i_dsrl_safe(&p, a1, a1, 23);
-# endif
+ uasm_i_mfc0(&p, a1, SMP_CPUID_REG);
+#else
+ UASM_i_MFC0(&p, a1, SMP_CPUID_REG);
+#endif
+ uasm_i_dsrl_safe(&p, a1, a1, SMP_CPUID_PTRSHIFT);
UASM_i_LA_mostly(&p, a2, pgdc);
UASM_i_ADDU(&p, a2, a2, a1);
UASM_i_SW(&p, a0, uasm_rel_lo(pgdc), a2);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH v3 0/4]Use scratch registers on XLR/XLS/XLP
2013-06-10 7:35 [PATCH v3 0/4]Use scratch registers on XLR/XLS/XLP Jayachandran C
` (3 preceding siblings ...)
2013-06-10 7:35 ` [PATCH 4/4] MIPS: Move definition of SMP processor id register to header file Jayachandran C
@ 2013-06-11 11:44 ` Jayachandran C.
4 siblings, 0 replies; 6+ messages in thread
From: Jayachandran C. @ 2013-06-11 11:44 UTC (permalink / raw)
To: linux-mips, ralf
On Mon, Jun 10, 2013 at 01:05:29PM +0530, Jayachandran C wrote:
> This set of patches enable the use of scratch registers on XLR/XLS and XLP
> (cop0 reg 22, sel 0-7) to optimize the generated TLB handlers.
Looks like I submitted an older version of this patchset - I will post the
updated version.
I have marked the patches as superseded in patchwork.
JC.
^ permalink raw reply [flat|nested] 6+ messages in thread