鸿蒙轻内核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 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切到内核空间的ID

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相关汇编代码。

如果大家想更加深入的学习 OpenHarmony 开发的内容,不妨可以参考以下相关学习文档进行学习,助你快速提升自己:

OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ......

系统架构分析:https://qr18.cn/CgxrRy

  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ......

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:https://qr21.cn/FV7h05
相关推荐
SameX1 小时前
鸿蒙 Next 电商应用安全支付与密码保护实践
前端·harmonyos
羊小猪~~1 小时前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
SuperHeroWu72 小时前
【HarmonyOS】键盘遮挡输入框UI布局处理
华为·harmonyos·压缩·keyboard·键盘遮挡·抬起
脉牛杂德2 小时前
多项式加法——C语言
数据结构·c++·算法
legend_jz2 小时前
STL--哈希
c++·算法·哈希算法
CSUC2 小时前
【C++】父类参数有默认值时子类构造函数列表中可以省略该参数
c++
Vanranrr2 小时前
C++ QT
java·c++·qt
鸿儒5172 小时前
C++ lambda 匿名函数
开发语言·c++
van叶~3 小时前
算法妙妙屋-------1.递归的深邃回响:二叉树的奇妙剪枝
c++·算法
knighthood20013 小时前
解决:ros进行gazebo仿真,rviz没有显示传感器数据
c++·ubuntu·ros