コード例 #1
0
ファイル: tlbex.c プロジェクト: qwerty1023/wive-rtnl-firmware
/*
 * TMP and PTR are scratch.
 * TMP will be clobbered, PTR will hold the pmd entry.
 */
static __init void
build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
		 unsigned int tmp, unsigned int ptr)
{
	long pgdc = (long)pgd_current;

	/*
	 * The vmalloc handling is not in the hotpath.
	 */
	uasm_i_dmfc0(p, tmp, C0_BADVADDR);
#ifdef MODULE_START
	uasm_il_bltz(p, r, tmp, label_module_alloc);
#else
	uasm_il_bltz(p, r, tmp, label_vmalloc);
#endif
	/* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */

#ifdef CONFIG_SMP
# ifdef  CONFIG_MIPS_MT_SMTC
	/*
	 * SMTC uses TCBind value as "CPU" index
	 */
	uasm_i_mfc0(p, ptr, C0_TCBIND);
	uasm_i_dsrl(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(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);
#else
	UASM_i_LA_mostly(p, ptr, pgdc);
	uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
#endif

	uasm_l_vmalloc_done(l, *p);

	if (PGDIR_SHIFT - 3 < 32)		/* get pgd offset in bytes */
		uasm_i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3);
	else
		uasm_i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32);

	uasm_i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
	uasm_i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
	uasm_i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
	uasm_i_ld(p, ptr, 0, ptr); /* get pmd pointer */
	uasm_i_dsrl(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
	uasm_i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3);
	uasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */
}
コード例 #2
0
static inline void
pg_addiu(u32 **buf, unsigned int reg1, unsigned int reg2, unsigned int off)
{
	if (cpu_has_64bit_gp_regs && DADDI_WAR && r4k_daddiu_bug()) {
		if (off > 0x7fff) {
			uasm_i_lui(buf, T9, uasm_rel_hi(off));
			uasm_i_addiu(buf, T9, T9, uasm_rel_lo(off));
		} else
			uasm_i_addiu(buf, T9, ZERO, off);
		uasm_i_daddu(buf, reg1, reg2, T9);
	} else {
		if (off > 0x7fff) {
			uasm_i_lui(buf, T9, uasm_rel_hi(off));
			uasm_i_addiu(buf, T9, T9, uasm_rel_lo(off));
			UASM_i_ADDU(buf, reg1, reg2, T9);
		} else
			UASM_i_ADDIU(buf, reg1, reg2, off);
	}
}