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>
This commit is contained in:
committed by
Ralf Baechle
parent
7c2740f1c1
commit
1b3a6e975c
@@ -91,7 +91,7 @@ enum opcode {
|
||||
insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
|
||||
insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
|
||||
insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
|
||||
insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
|
||||
insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
|
||||
insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
|
||||
insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
|
||||
insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
|
||||
@@ -134,7 +134,6 @@ static __initdata struct insn insn_table[] = {
|
||||
{ insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE },
|
||||
{ insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE },
|
||||
{ insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE },
|
||||
{ insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE },
|
||||
{ insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD },
|
||||
{ insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 },
|
||||
{ insn_j, M(j_op,0,0,0,0,0), JIMM },
|
||||
@@ -366,7 +365,6 @@ I_u2u1u3(_dsll);
|
||||
I_u2u1u3(_dsll32);
|
||||
I_u2u1u3(_dsra);
|
||||
I_u2u1u3(_dsrl);
|
||||
I_u2u1u3(_dsrl32);
|
||||
I_u3u1u2(_dsubu);
|
||||
I_0(_eret);
|
||||
I_u1(_j);
|
||||
@@ -944,34 +942,29 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
|
||||
/* No i_nop needed here, since the next insn doesn't touch TMP. */
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
# ifdef CONFIG_BUILD_ELF64
|
||||
/*
|
||||
* 64 bit SMP has the lower part of &pgd_current[smp_processor_id()]
|
||||
* 64 bit SMP running in XKPHYS has smp_processor_id() << 3
|
||||
* stored in CONTEXT.
|
||||
*/
|
||||
if (in_compat_space_p(pgdc)) {
|
||||
i_dmfc0(p, ptr, C0_CONTEXT);
|
||||
i_dsra(p, ptr, ptr, 23);
|
||||
i_ld(p, ptr, 0, ptr);
|
||||
} else {
|
||||
#ifdef CONFIG_BUILD_ELF64
|
||||
i_dmfc0(p, ptr, C0_CONTEXT);
|
||||
i_dsrl(p, ptr, ptr, 23);
|
||||
i_dsll(p, ptr, ptr, 3);
|
||||
i_LA_mostly(p, tmp, pgdc);
|
||||
i_daddu(p, ptr, ptr, tmp);
|
||||
i_dmfc0(p, tmp, C0_BADVADDR);
|
||||
i_ld(p, ptr, rel_lo(pgdc), ptr);
|
||||
#else
|
||||
i_dmfc0(p, ptr, C0_CONTEXT);
|
||||
i_lui(p, tmp, rel_highest(pgdc));
|
||||
i_dsll(p, ptr, ptr, 9);
|
||||
i_daddiu(p, tmp, tmp, rel_higher(pgdc));
|
||||
i_dsrl32(p, ptr, ptr, 0);
|
||||
i_and(p, ptr, ptr, tmp);
|
||||
i_dmfc0(p, tmp, C0_BADVADDR);
|
||||
i_ld(p, ptr, 0, ptr);
|
||||
#endif
|
||||
}
|
||||
i_dmfc0(p, ptr, C0_CONTEXT);
|
||||
i_dsrl(p, ptr, ptr, 23);
|
||||
i_LA_mostly(p, tmp, pgdc);
|
||||
i_daddu(p, ptr, ptr, tmp);
|
||||
i_dmfc0(p, tmp, C0_BADVADDR);
|
||||
i_ld(p, ptr, rel_lo(pgdc), ptr);
|
||||
# else
|
||||
/*
|
||||
* 64 bit SMP running in compat space has the lower part of
|
||||
* &pgd_current[smp_processor_id()] stored in CONTEXT.
|
||||
*/
|
||||
if (!in_compat_space_p(pgdc))
|
||||
panic("Invalid page directory address!");
|
||||
|
||||
i_dmfc0(p, ptr, C0_CONTEXT);
|
||||
i_dsra(p, ptr, ptr, 23);
|
||||
i_ld(p, ptr, 0, ptr);
|
||||
# endif
|
||||
#else
|
||||
i_LA_mostly(p, ptr, pgdc);
|
||||
i_ld(p, ptr, rel_lo(pgdc), ptr);
|
||||
@@ -1028,7 +1021,6 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
|
||||
i_mfc0(p, ptr, C0_CONTEXT);
|
||||
i_LA_mostly(p, tmp, pgdc);
|
||||
i_srl(p, ptr, ptr, 23);
|
||||
i_sll(p, ptr, ptr, 2);
|
||||
i_addu(p, ptr, tmp, ptr);
|
||||
#else
|
||||
i_LA_mostly(p, ptr, pgdc);
|
||||
|
Reference in New Issue
Block a user