其他分享
首页 > 其他分享> > optee中的arm64的virt_to_phys的实现

optee中的arm64的virt_to_phys的实现

作者:互联网


★★★ 友情链接 : 个人博客导读首页—点击此处 ★★★

在optee中 arm_va2pa_helper实现了virtual addr转换phys addr,具体实现如下

/*virt transform to phys, regardless of the virt is ddr addr or register addr*/
	arm_va2pa_helper((void *)buf_in, &phy_in);
	arm_va2pa_helper((void *)buf_out, &phy_out);
#include <linux/module.h>

#define BIT32(nr)		((1 & 0xffffffff) << (nr))
#define BIT64(nr)		((1 & 0xffffffffffffffff) << (nr))

#define PAR_F			BIT32(0)
#define PAR_PA_SHIFT		12
#define PAR_PA_MASK		(BIT64(36) - 1)

#define DEFINE_REG_READ_FUNC_(reg, type, asmreg)	\
static inline type read_##reg(void)			\
{							\
	type val;					\
							\
	asm volatile("mrs %0, " #asmreg : "=r" (val));	\
	return val;					\
}

#define DEFINE_U64_REG_READ_FUNC(reg) \
		DEFINE_REG_READ_FUNC_(reg, uint64_t, reg)

DEFINE_U64_REG_READ_FUNC(par_el1)

static inline void write_at_s1e1r(uint64_t va)
{
	asm volatile ("at	S1E1R, %0" : : "r" (va));
}

bool arm_va2pa_helper(void *va, uint64_t *pa)
{
	uint64_t par;
	uint64_t par_pa_mask;
	bool ret = false;

	local_irq_disable();
	write_at_s1e1r((uint64_t)va);
	isb();
	par = read_par_el1();
	par_pa_mask = PAR_PA_MASK;

	if (par & PAR_F)
		goto out;
	*pa = (par & (par_pa_mask << PAR_PA_SHIFT)) |
		((uint64_t)va & ((1 << PAR_PA_SHIFT) - 1));

	ret = true;
out:
	local_irq_enable();;
	return ret;
}
EXPORT_SYMBOL(arm_va2pa_helper);

总结一下arm_va2pa_helper,其实就是将虚拟地址写入MMU寄存器,然后再读取另外一个寄存器获取物理地址

标签:optee,addr,helper,va2pa,virt,phys,arm
来源: https://blog.51cto.com/u_15278218/2930997