鸿蒙轻内核A核源码分析系列六 MMU协处理器(2)
【摘要】 3、MMU汇编代码在arch\arm\arm\include\arm.h文件中,封装了CP15协处理器相关的寄存器操作汇编函数。我们主要看下MMU相关的部分。 3.1 CP15 C2 TTBR转换表基地址寄存器代码比较简单,结合下图,自行查看即可。该图来自《ARM Cortex-A9 Technical Reference Manual r4p1》CP15 system control r...
3、MMU汇编代码
在arch\arm\arm\include\arm.h
文件中,封装了CP15协处理器相关的寄存器操作汇编函数。我们主要看下MMU相关的部分。
3.1 CP15 C2 TTBR转换表基地址寄存器
代码比较简单,结合下图,自行查看即可。该图来自《ARM Cortex-A9 Technical Reference Manual r4p1》CP15 system control registers grouped by CRn order部分。
STATIC INLINE UINT32 OsArmReadTtbr(VOID)
{
UINT32 val;
__asm__ volatile("mrc p15, 0, %0, c2,c0,0" : "=r"(val));
return val;
}
STATIC INLINE VOID OsArmWriteTtbr(UINT32 val)
{
__asm__ volatile("mcr p15, 0, %0, c2,c0,0" ::"r"(val));
__asm__ volatile("isb" ::: "memory");
}
STATIC INLINE UINT32 OsArmReadTtbr0(VOID)
{
UINT32 val;
__asm__ volatile("mrc p15, 0, %0, c2,c0,0" : "=r"(val));
return val;
}
STATIC INLINE VOID OsArmWriteTtbr0(UINT32 val)
{
__asm__ volatile("mcr p15, 0, %0, c2,c0,0" ::"r"(val));
__asm__ volatile("isb" ::: "memory");
}
STATIC INLINE UINT32 OsArmReadTtbr1(VOID)
{
UINT32 val;
__asm__ volatile("mrc p15, 0, %0, c2,c0,1" : "=r"(val));
return val;
}
STATIC INLINE VOID OsArmWriteTtbr1(UINT32 val)
{
__asm__ volatile("mcr p15, 0, %0, c2,c0,1" ::"r"(val));
__asm__ volatile("isb" ::: "memory");
}
STATIC INLINE UINT32 OsArmReadTtbcr(VOID)
{
UINT32 val;
__asm__ volatile("mrc p15, 0, %0, c2,c0,2" : "=r"(val));
return val;
}
STATIC INLINE VOID OsArmWriteTtbcr(UINT32 val)
{
__asm__ volatile("mcr p15, 0, %0, c2,c0,2" ::"r"(val));
__asm__ volatile("isb" ::: "memory");
}
3.2 CP15 C7 高速缓存寄存器
代码比较简单,结合下图,自行查看即可。该图是C7寄存器的部分截图。
STATIC INLINE UINT32 OsArmReadBpiall(VOID)
{
UINT32 val;
__asm__ volatile("mrc p15, 0, %0, c7,c5,6" : "=r"(val));
return val;
}
STATIC INLINE VOID OsArmWriteBpiall(UINT32 val)
{
__asm__ volatile("mcr p15, 0, %0, c7,c5,6" ::"r"(val));
__asm__ volatile("isb" ::: "memory");
}
STATIC INLINE UINT32 OsArmReadBpiallis(VOID)
{
UINT32 val;
__asm__ volatile("mrc p15, 0, %0, c7,c1,6" : "=r"(val));
return val;
}
STATIC INLINE VOID OsArmWriteBpiallis(UINT32 val)
{
__asm__ volatile("mcr p15, 0, %0, c7,c1,6" ::"r"(val));
__asm__ volatile("isb" ::: "memory");
}
3.3 CP15 C13 进程标识符寄存器
代码比较简单,结合下图,自行查看即可。
STATIC INLINE UINT32 OsArmReadContextidr(VOID)
{
UINT32 val;
__asm__ volatile("mrc p15, 0, %0, c13,c0,1" : "=r"(val));
return val;
}
STATIC INLINE VOID OsArmWriteContextidr(UINT32 val)
{
__asm__ volatile("mcr p15, 0, %0, c13,c0,1" ::"r"(val));
__asm__ volatile("isb" ::: "memory");
}
4 MMU上下文切换
在之前的系列,我们了解到每个用户进程都有独立的进程空间。在进程切换时,MMU上下文也会切换,相应的函数为LOS_ArchMmuContextSwitch()
。快速分析下该函数的代码。
⑴处读取TTBCR寄存器的状态值,如果传入参数archMmu
不为空,执行⑵使能TTBR0,否则执行⑶使其失能TTBR0。⑷处把内核地址空间的进程空间标识符asid写入C13寄存器。⑸处更新TTB页表基地址和TTB状态信息到相应寄存器。⑹处把进程空间的进程标识符写入C13寄存器。
VOID LOS_ArchMmuContextSwitch(LosArchMmu *archMmu)
{
UINT32 ttbr;
⑴ UINT32 ttbcr = OsArmReadTtbcr();
if (archMmu) {
⑵ ttbr = MMU_TTBRx_FLAGS | (archMmu->physTtb);
/* enable TTBR0 */
ttbcr &= ~MMU_DESCRIPTOR_TTBCR_PD0;
} else {
⑶ ttbr = 0;
/* disable TTBR0 */
ttbcr |= MMU_DESCRIPTOR_TTBCR_PD0;
}
#ifdef LOSCFG_KERNEL_VM
/* from armv7a arm B3.10.4, we should do synchronization changes of ASID and TTBR. */
⑷ OsArmWriteContextidr(LOS_GetKVmSpace()->archMmu.asid);
ISB;
#endif
⑸ OsArmWriteTtbr0(ttbr);
ISB;
OsArmWriteTtbcr(ttbcr);
ISB;
#ifdef LOSCFG_KERNEL_VM
if (archMmu) {
⑹ OsArmWriteContextidr(archMmu->asid);
ISB;
}
#endif
}
小结
本文介绍了ARM CP15协处理器的知识,接着介绍下协处理器相关的汇编指令,最后分析下MMU相关汇编代码。感谢阅读,有什么问题,请留言。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)