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:
Thiemo Seufer
2005-04-01 14:07:13 +00:00
committed by Ralf Baechle
parent 7c2740f1c1
commit 1b3a6e975c
5 changed files with 34 additions and 41 deletions

View File

@@ -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);