写点什么

鸿蒙轻内核源码分析:MMU 协处理器

  • 2021 年 12 月 15 日
  • 本文字数:3488 字

    阅读完需:约 11 分钟

摘要:本系列首先了解下 ARM CP15 协处理器的知识,接着介绍下协处理器相关的汇编指令,最后分析下 MMU 相关汇编代码。

 

本文分享自华为云社区《鸿蒙轻内核A核源码分析系列六 MMU协处理器》,作者:zhushy。

1、ARM C15 协处理器


在 ARM 嵌入式应用系统中, 很多系统控制由 ARM CP15 协处理器来完成的。CP15 协处理器包含编号 0-15 的 16 个 32 位的寄存器。例如,ARM 处理器使用 C15 协处理器的寄存器来控制 cache、TCM(Tightly-Coupled Memory)和存储器管理。CP15 的各个寄存器的概要信息如下图,图片来自官方资料《ARM® Cortex™-A Series Version: 4.0 Programmer’s Guide》。





​在这些 C15 寄存器中和 MMU 关系较大的有 C2、C7、C17 寄存器,这些寄存器的作用,从上图可以看出,分别是:


  • CP15 C2 寄存器

Memory protection and control registers,内存保护和控制寄存器,包含 Translation Table Base Register 0 (TTBR0)、Translation Table Base Register 1 (TTBR1)和 Translation Table Base Control Register (TTBCR)。TTBR0、TTBR1 是 L1 转换页表的基地址,TTCR 控制 TTBR0 和 TTBR1 的使用。


  • CP15 C7 寄存器

Cache and branch predictor maintenance functions、Data and instruction barrier operations 用于高速缓存和写缓存控制。


  • CP15 C13 寄存器

Context ID Register (CONTEXTIDR)、Software thread ID registers 用于保存进程标识符(asid 地址空间编号)。

2、ARM C15 协处理器汇编指令


访问 CP15 寄存器的指令主要是 MCR 和 MRC 这两个指令。本小节详细介绍下这 2 个汇编指令。先看下指令的含义,MCR 是 ARM 处理器寄存器到协处理器寄存器的数据传送指令,英文为 Move CPU register to coprocessor register,MRC 是协处理器寄存器到 ARM 处理器寄存器的数据传送指令,英文为 Move from coprocessor register to CPU register。这 2 个指令的语义格式如下,可以看出语义格式是一样的,但是读取写入含义会有差异。MCR 是读取 Rt 寄存器写入协处理器寄存器 CRn、CRm,而 MRC 是读取协处理器寄存器 CRn、CRm 写入 Rt 寄存器。


MCR{cond} coproc, #opcode1, Rt, CRn, CRm{, #opcode2}MRC{cond} coproc, #opcode1, Rt, CRn, CRm{, #opcode2}
复制代码


​MCR 详细的语义介绍如下:


SyntaxMCR{cond} coproc, #opcode1, Rt, CRn, CRm{, #opcode2}
where:condis an optional condition code. 可选的条件码。coprocis the name of the coprocessor the instruction is for. The standard name is pn, where n is an integer in the range 0 to 15.协处理器的名称,标准名称为pn,其中n为0-15,例如p14、p15。opcode1is a 3-bit coprocessor-specific opcode. 3位的操作码。opcode2is an optional 3-bit coprocessor-specific opcode.可选的3位操作码。Rtis an ARM source register. Rt must not be PC. 要读取的ARM寄存器,不能为PC寄存器。CRn, CRmare coprocessor registers.要写入的协处理器寄存器。
复制代码


MRC 详细的语义介绍如下:


SyntaxMRC{cond} coproc, #opcode1, Rt, CRn, CRm{, #opcode2}
where:condis an optional condition code. 可选的条件码。coprocis the name of the coprocessor the instruction is for. The standard name is pn, where n is an integer in the range 0 to 15.协处理器的名称,标准名称为pn,其中n为0-15,例如p14、p15。opcode1is a 3-bit coprocessor-specific opcode.3位的操作码。opcode2is an optional 3-bit coprocessor-specific opcode.可选的3位操作码Rtis the ARM destination register. Rt must not be PC.要写入的ARM寄存器,不能为PC寄存器。Rt can be APSR_nzcv. This means that the coprocessor executes an instruction that changes the value of the condition flags in the APSR. Rt也可以为APSR_nzcv。CRn, CRmare coprocessor registers.要读取的协处理器寄存器。
复制代码


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 相关汇编代码。感谢阅读,有什么问题,请留言。


点击关注,第一时间了解华为云新鲜技术~

发布于: 1 小时前阅读数: 4
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
鸿蒙轻内核源码分析:MMU协处理器