摘要:本系列首先了解下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详细的语义介绍如下:

Syntax
MCR{cond} coproc, #opcode1, Rt, CRn, CRm{, #opcode2} where:
cond
is an optional condition code. 可选的条件码。
coproc
is 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。
opcode1
is a 3-bit coprocessor-specific opcode. 3位的操作码。
opcode2
is an optional 3-bit coprocessor-specific opcode.可选的3位操作码。
Rt
is an ARM source register. Rt must not be PC. 要读取的ARM寄存器,不能为PC寄存器。
CRn, CRm
are coprocessor registers.要写入的协处理器寄存器。

MRC详细的语义介绍如下:

Syntax
MRC{cond} coproc, #opcode1, Rt, CRn, CRm{, #opcode2} where:
cond
is an optional condition code. 可选的条件码。
coproc
is 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。
opcode1
is a 3-bit coprocessor-specific opcode.3位的操作码。
opcode2
is an optional 3-bit coprocessor-specific opcode.可选的3位操作码
Rt
is 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, CRm
are 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相关汇编代码。感谢阅读,有什么问题,请留言。

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

鸿蒙轻内核源码分析:MMU协处理器的更多相关文章

  1. 鸿蒙轻内核源码分析:文件系统LittleFS

    摘要:本文先介绍下LFS文件系统结构体的结构体和全局变量,然后分析下LFS文件操作接口. 本文分享自华为云社区<# 鸿蒙轻内核M核源码分析系列二一 02 文件系统LittleFS>,作者: ...

  2. 鸿蒙轻内核源码分析:文件系统FatFS

    摘要:本文为大家介绍FatFS文件系统结构体的结构体和全局变量,并分析FatFS文件操作接口. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列二一 03 文件系统FatFS>,作者:zh ...

  3. v82.01 鸿蒙内核源码分析 (协处理器篇) | CPU 的好帮手 | 百篇博客分析 OpenHarmony 源码

    本篇关键词:CP15 .MCR.MRC.ASID.MMU 硬件架构相关篇为: v65.01 鸿蒙内核源码分析(芯片模式) | 回顾芯片行业各位大佬 v66.03 鸿蒙内核源码分析(ARM架构) | A ...

  4. 鸿蒙内核源码分析(寄存器篇) | 小强乃宇宙最忙存储器 | 百篇博客分析OpenHarmony源码 | v38.02

    百篇博客系列篇.本篇为: v38.xx 鸿蒙内核源码分析(寄存器篇) | 小强乃宇宙最忙存储器 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CPU在哪 ...

  5. 鸿蒙内核源码分析(工作模式篇) | CPU是韦小宝,七个老婆 | 百篇博客分析OpenHarmony源码 | v36.04

    百篇博客系列篇.本篇为: v36.xx 鸿蒙内核源码分析(工作模式篇) | CPU是韦小宝,七个老婆 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CP ...

  6. 鸿蒙内核源码分析(内存汇编篇) | 谁是虚拟内存实现的基础 | 百篇博客分析OpenHarmony源码 | v14.14

    百篇博客系列篇.本篇为: v14.xx 鸿蒙内核源码分析(内存汇编篇) | 谁是虚拟内存实现的基础 | 51.c.h .o 内存管理相关篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有 ...

  7. v87.01 鸿蒙内核源码分析 (内核启动篇) | 从汇编到 main () | 百篇博客分析 OpenHarmony 源码

    本篇关键词:内核重定位.MMU.SVC栈.热启动.内核映射表 内核汇编相关篇为: v74.01 鸿蒙内核源码分析(编码方式) | 机器指令是如何编码的 v75.03 鸿蒙内核源码分析(汇编基础) | ...

  8. 鸿蒙内核源码分析(构建工具篇) | 顺瓜摸藤调试鸿蒙构建过程 | 百篇博客分析OpenHarmony源码 | v59.01

    百篇博客系列篇.本篇为: v59.xx 鸿蒙内核源码分析(构建工具篇) | 顺瓜摸藤调试鸿蒙构建过程 | 51.c.h.o 编译构建相关篇为: v50.xx 鸿蒙内核源码分析(编译环境篇) | 编译鸿 ...

  9. 鸿蒙内核源码分析(编译脚本篇) | 如何防编译环境中的牛皮癣 | 百篇博客分析OpenHarmony源码 | v58.01

    百篇博客系列篇.本篇为: v58.xx 鸿蒙内核源码分析(环境脚本篇) | 编译鸿蒙原来如此简单 | 51.c.h.o 本篇用两个脚本完成鸿蒙(L1)的编译环境安装/源码下载/编译过程,让编译,调试鸿 ...

  10. 鸿蒙内核源码分析(进程镜像篇)|ELF是如何被加载运行的? | 百篇博客分析OpenHarmony源码 | v56.01

    百篇博客系列篇.本篇为: v56.xx 鸿蒙内核源码分析(进程映像篇) | ELF是如何被加载运行的? | 51.c.h.o 加载运行相关篇为: v51.xx 鸿蒙内核源码分析(ELF格式篇) | 应 ...

随机推荐

  1. Stride游戏引擎试毒

    想找别的引擎用, 主要还是因为unity和国内盗版用户的互相伤害, 就算用免费的个人版也要不停的验证. stride引擎, 原名xenko, 再原名paradox... 一开始是日本厂商开发的引擎, ...

  2. 程序是如何在计算机上被执行的?(下篇:cpu工作原理)

    本文接上文程序是如何在计算机上被执行的?(上篇:软件部分),主要内容是机器语言如何在计算机硬件上运行,关于逻辑门,加法器,布尔运算,亦即,cpu的工作原理. 1.逻辑门 以下图片是<三体> ...

  3. Python 正则表达式(RegEx)指南

    正则表达式(RegEx)是一系列字符,形成了一个搜索模式.RegEx 可用于检查字符串是否包含指定的搜索模式. RegEx 模块 Python 中有一个内置的包叫做 re,它可以用于处理正则表达式.导 ...

  4. Android 的异步消息处理机制

    前言 Android中的异步消息处理机制主要有四部分:Message.Handler.MessageQuene.Looper.这一消息处理机制也称为Handler机制.Handler机制是支撑整个An ...

  5. 初窥门径,从大模型到内容生成看AI新次元

    视频云AI进化新纪元. 最近Gartner发布2024年十大战略技术趋势,AI显然成为其背后共同的主题.全民化的生成式人工智能.AI增强开发.智能应用......我们正在进入一个AI新纪元. 从Cha ...

  6. 一个.Net开源的协作办公套件,包括文档、表格、演示文稿和表单

    推荐一个开源的文档协作办公套件,可以很好的满足团队对方便.高效.安全的方式来处理文档工作,促进团队协作和信息共享. 项目简介 ONLYOFFICE 是一个开源的办公套件,包括文档.表格.演示文稿和表单 ...

  7. [编程]UML语言:理论之光与实践之惑

    UML介绍及现状 UML(统一建模语言)是软件工程领域中具有悠久历史的一种模型化语言工具.它通过标准化的图形符号体系,使得软件系统的蓝图能够被更直观地表达出来.UML诞生于20世纪90年代,经过多年积 ...

  8. 品牌全渠道营销系统如何与不同经销商ERP打通

    品牌商在与各经销商ERP系统打通方面面临的挑战.传统的ERP系统往往使得数据收集和合作变得繁琐且低效,导致市场响应迟缓,影响整体的供应链管理和市场决策.我们的解决方案旨在破解这一难题,提供一个全渠道营 ...

  9. java集合框架(三)ArrayList常见方法的使用

    @[toc]## 一.什么是ArrarListArrayList是Java中的一个动态数组类,可以根据实际需要自动调整数组的大小.ArrayList是基于数组实现的,它内部维护的是一个Object数组 ...

  10. 大数据开发要学什么java还是python?

    在大数据开发领域,Java和Python都是备受青睐的编程语言.它们分别具有各自独特的特点和优势,在大数据处理方面也有不同的应用场景. 以下是对Java和Python在大数据开发中的应用.优势以及学习 ...