aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorThiemo Seufer <ths@networkno.de>2005-04-01 09:07:13 -0500
committerRalf Baechle <ralf@linux-mips.org>2005-10-29 14:31:00 -0400
commit1b3a6e975cbe81c5abc55e4c1b9f5b5250c5f20e (patch)
tree541db3912172f82d30244cf215b1a1b91d8c6f7f /arch
parent7c2740f1c1a7ff2767a92042f39edad7fad95c92 (diff)
Fix 64bit SMP TLB handler and stack frame handling, optimize 32bit SMP
TLB handlers a bit, match definitions in pgtable-{32,64}.h better. Signed-off-by: Thiemo Seufer <ths@networkno.de> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/kernel/head.S1
-rw-r--r--arch/mips/mm/tlbex.c50
2 files changed, 22 insertions, 29 deletions
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 124c27e908f4..9f6927169358 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -157,6 +157,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
157 LONG_S a2, fw_arg2 157 LONG_S a2, fw_arg2
158 LONG_S a3, fw_arg3 158 LONG_S a3, fw_arg3
159 159
160 MTC0 zero, CP0_CONTEXT # clear context register
160 PTR_LA $28, init_thread_union 161 PTR_LA $28, init_thread_union
161 PTR_ADDIU sp, $28, _THREAD_SIZE - 32 162 PTR_ADDIU sp, $28, _THREAD_SIZE - 32
162 set_saved_sp sp, t0, t1 163 set_saved_sp sp, t0, t1
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index bcf87a2b554c..018f7527a724 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -91,7 +91,7 @@ enum opcode {
91 insn_addu, insn_addiu, insn_and, insn_andi, insn_beq, 91 insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
92 insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, 92 insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
93 insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0, 93 insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
94 insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, 94 insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
95 insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, 95 insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
96 insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0, 96 insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
97 insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, 97 insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
@@ -134,7 +134,6 @@ static __initdata struct insn insn_table[] = {
134 { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE }, 134 { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE },
135 { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE }, 135 { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE },
136 { insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE }, 136 { insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE },
137 { insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE },
138 { insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD }, 137 { insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD },
139 { insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 }, 138 { insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 },
140 { insn_j, M(j_op,0,0,0,0,0), JIMM }, 139 { insn_j, M(j_op,0,0,0,0,0), JIMM },
@@ -366,7 +365,6 @@ I_u2u1u3(_dsll);
366I_u2u1u3(_dsll32); 365I_u2u1u3(_dsll32);
367I_u2u1u3(_dsra); 366I_u2u1u3(_dsra);
368I_u2u1u3(_dsrl); 367I_u2u1u3(_dsrl);
369I_u2u1u3(_dsrl32);
370I_u3u1u2(_dsubu); 368I_u3u1u2(_dsubu);
371I_0(_eret); 369I_0(_eret);
372I_u1(_j); 370I_u1(_j);
@@ -944,34 +942,29 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
944 /* No i_nop needed here, since the next insn doesn't touch TMP. */ 942 /* No i_nop needed here, since the next insn doesn't touch TMP. */
945 943
946#ifdef CONFIG_SMP 944#ifdef CONFIG_SMP
945# ifdef CONFIG_BUILD_ELF64
947 /* 946 /*
948 * 64 bit SMP has the lower part of &pgd_current[smp_processor_id()] 947 * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
949 * stored in CONTEXT. 948 * stored in CONTEXT.
950 */ 949 */
951 if (in_compat_space_p(pgdc)) { 950 i_dmfc0(p, ptr, C0_CONTEXT);
952 i_dmfc0(p, ptr, C0_CONTEXT); 951 i_dsrl(p, ptr, ptr, 23);
953 i_dsra(p, ptr, ptr, 23); 952 i_LA_mostly(p, tmp, pgdc);
954 i_ld(p, ptr, 0, ptr); 953 i_daddu(p, ptr, ptr, tmp);
955 } else { 954 i_dmfc0(p, tmp, C0_BADVADDR);
956#ifdef CONFIG_BUILD_ELF64 955 i_ld(p, ptr, rel_lo(pgdc), ptr);
957 i_dmfc0(p, ptr, C0_CONTEXT); 956# else
958 i_dsrl(p, ptr, ptr, 23); 957 /*
959 i_dsll(p, ptr, ptr, 3); 958 * 64 bit SMP running in compat space has the lower part of
960 i_LA_mostly(p, tmp, pgdc); 959 * &pgd_current[smp_processor_id()] stored in CONTEXT.
961 i_daddu(p, ptr, ptr, tmp); 960 */
962 i_dmfc0(p, tmp, C0_BADVADDR); 961 if (!in_compat_space_p(pgdc))
963 i_ld(p, ptr, rel_lo(pgdc), ptr); 962 panic("Invalid page directory address!");
964#else 963
965 i_dmfc0(p, ptr, C0_CONTEXT); 964 i_dmfc0(p, ptr, C0_CONTEXT);
966 i_lui(p, tmp, rel_highest(pgdc)); 965 i_dsra(p, ptr, ptr, 23);
967 i_dsll(p, ptr, ptr, 9); 966 i_ld(p, ptr, 0, ptr);
968 i_daddiu(p, tmp, tmp, rel_higher(pgdc)); 967# endif
969 i_dsrl32(p, ptr, ptr, 0);
970 i_and(p, ptr, ptr, tmp);
971 i_dmfc0(p, tmp, C0_BADVADDR);
972 i_ld(p, ptr, 0, ptr);
973#endif
974 }
975#else 968#else
976 i_LA_mostly(p, ptr, pgdc); 969 i_LA_mostly(p, ptr, pgdc);
977 i_ld(p, ptr, rel_lo(pgdc), ptr); 970 i_ld(p, ptr, rel_lo(pgdc), ptr);
@@ -1028,7 +1021,6 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
1028 i_mfc0(p, ptr, C0_CONTEXT); 1021 i_mfc0(p, ptr, C0_CONTEXT);
1029 i_LA_mostly(p, tmp, pgdc); 1022 i_LA_mostly(p, tmp, pgdc);
1030 i_srl(p, ptr, ptr, 23); 1023 i_srl(p, ptr, ptr, 23);
1031 i_sll(p, ptr, ptr, 2);
1032 i_addu(p, ptr, tmp, ptr); 1024 i_addu(p, ptr, tmp, ptr);
1033#else 1025#else
1034 i_LA_mostly(p, ptr, pgdc); 1026 i_LA_mostly(p, ptr, pgdc);