0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

王程 来源:jf_75796907 作者:jf_75796907 2024-02-20 14:28 次阅读

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》。

wKgZomXURhaAGcYoAAMU1aaKtPg526.png

wKgaomXURh-AUmc6AAF_vM3IDzA715.png

wKgaomXURjKAZrqSAAHXMTBCZzI662.png


在这些 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 汇编代码

在 archarmarmincludearm.h 文件中,封装了 CP15 协处理器相关的寄存器操作汇编函数。我们主要看下 MMU 相关的部分。

3.1 CP15 C2 TTBR 转换表基地址寄存器

代码比较简单,结合下图,自行查看即可。该图来自《ARM Cortex-A9 Technical Reference Manual r4p1》CP15 system control registers grouped by CRn order 部分。

wKgZomXURkuAVcDTAAC0gU-1zPI091.png

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 寄存器的部分截图。

wKgZomXURlWASRI-AAD0Y7kcroU999.png

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 进程标识符寄存器

代码比较简单,结合下图,自行查看即可。

wKgZomXURl6AMvzCAACc0RjQUio347.png

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 }



审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 处理器
    +关注

    关注

    68

    文章

    18275

    浏览量

    222160
  • ARM
    ARM
    +关注

    关注

    134

    文章

    8651

    浏览量

    361782
  • 源码
    +关注

    关注

    8

    文章

    573

    浏览量

    28586
  • MMU
    MMU
    +关注

    关注

    0

    文章

    91

    浏览量

    17940
  • 鸿蒙
    +关注

    关注

    55

    文章

    1629

    浏览量

    42120
收藏 人收藏

    评论

    相关推荐

    AOSP源码定制-内核驱动编写

    有时候为了分析一些壳的检测,需要在内核层面对读写相关的操作进行监控,每次去修改对应的内核源码编译重刷过于耗时耗力,这里就来尝试编写一个内核
    的头像 发表于 04-23 11:15 88次阅读
    AOSP<b class='flag-5'>源码</b>定制-<b class='flag-5'>内核</b>驱动编写

    鸿蒙内核源码分析:Newlib C

    使用 Musl C 库的时候,内核提供了基于 LOS_XXX 适配实现 pthread、mqeue、fs、semaphore、time 等模块的 posix 接口(//kernel/liteos_m
    的头像 发表于 02-18 15:41 244次阅读
    <b class='flag-5'>鸿蒙</b>轻<b class='flag-5'>内核</b><b class='flag-5'>源码</b><b class='flag-5'>分析</b>:Newlib C

    获取Linux内核源码的方法

    (ELF1/ELF1S开发板及显示屏)Linux内核是操作系统中最核心的部分,它负责管理计算机硬件资源,并提供对应用程序和其他系统组件的访问接口,控制着计算机的内存、处理器、设备驱动程序和文
    的头像 发表于 12-13 09:49 299次阅读
    获取Linux<b class='flag-5'>内核</b><b class='flag-5'>源码</b>的方法

    MMU中的页命中、缺页介绍

    页命中、缺页 (1)页命中 • a) 处理器要对虚拟地址VA进行访问。 • b) MMU的TLB没有命中,通过TWU遍历主存页表中的PTEA(PTE地址)。 • c) 主存向MMU返回PTE
    的头像 发表于 11-26 16:19 428次阅读
    <b class='flag-5'>MMU</b>中的页命中、缺页介绍

    ARM处理器中控制MMU功能的过程

    MMU是Memory Manage Unit的缩写,即存储管理单元的意思。
    发表于 09-11 17:51 509次阅读
    ARM<b class='flag-5'>处理器</b>中控制<b class='flag-5'>MMU</b>功能的过程

    ARM核心类型和修订标识的应用说明

    ARM核心通过两种机制进行识别。 第一种是通过系统控制处理器的寄存0,也称为处理器15或CP15。 CP15仅在包含
    发表于 08-23 06:55

    关于串口组以及处理器如何加载的问题

    ,所属USB始终被划入dialout组,进而造成在make upload 时无法找到相应设备。 如何解决? 2。关于处理器nice接口,现在已经有了一个硬件功能模块,但是不知道如何通过nice接口进行
    发表于 08-16 08:05

    请问nice处理器可以处理矩阵的乘法吗?

    ; :\"=r\"(zero) :\"r\"(addr));} 这里把addr赋给x0,但是x0作为零寄存不会保存任何信息? 然后func3和func7定义为2,2的含义是? .insn是否为实现访问处理器的意思?
    发表于 08-16 08:00

    NICE处理器最多可以处理多少个周期再抬高nice_rsp_valid啊?

    NICE处理器最多可以处理多少个周期再抬高nice_rsp_valid啊?
    发表于 08-16 07:56

    如何用处理器拓展指令实现更高级运算呢?

    按照这句话的意思,处理器拓展指令只能实现读写操作吗,官方的案例貌似也只是读写指令。那如何用处理器拓展指令实现更高级运算呢,用内联汇编吗
    发表于 08-16 07:41

    关于蜂鸟E203处理器参考示例的问题

    问题一:在vivado中编写约束文件时,由于nice接口的指令是由CPU、处理器和内存互相发送的,因此是否只需要约束clk和复位信号即可? 问题二:从软件示例程序中可知,数据是由软件输入的,那
    发表于 08-16 07:24

    请问E203 Core和NICE处理器的主频各是多少?

    请问E203 Core和 NICE处理器的主频各是多少?
    发表于 08-12 08:06

    ARM922T处理器技术参考手册

    ARM922T处理器是通用ARM9TDMI系列的一员微处理器,包括:•ARM9TDMI(核心)•ARM940T(核心加4K和4K缓存和保护单元)•ARM920T(核心加16K和16K缓存以及MMU
    发表于 08-02 15:44

    ARM920T处理器技术参考手册

    ARM920T处理器是通用微处理器ARM9TDMI系列的成员,包括: •ARM9TDMI(核心)•ARM940T(核心加缓存和保护单元)•ARM920T(核心+缓存和MMU)。 ARM9TDMI
    发表于 08-02 13:05

    ARM7TDMI (Rev 3)核心处理器产品概述

    ARM7系列包括ARM7TDMI、ARM7TDMI-S、ARM720T和ARM7EJ-S处理器。ARM7TDMI内核是业界应用最广泛的32位嵌入式risc微处理器解决方案。ARM7TDMI解决方案
    发表于 08-02 10:25