cp15 协处理代码注解

    百图画鸿蒙 + 百文说内核 + 百万注源码  => 挖透鸿蒙内核源码
    鸿蒙研究站 | http://weharmonyos.com (国内)
              | https://weharmony.github.io (国外)
    oschina | https://my.oschina.net/weharmony
    博客园 | https://www.cnblogs.com/weharmony/
    知乎 | https://www.zhihu.com/people/weharmonyos
    csdn | https://blog.csdn.net/kuangyufei
    51cto | https://harmonyos.51cto.com/column/34
    掘金 | https://juejin.cn/user/756888642000808
    公众号 | 鸿蒙研究站 (weharmonyos)
上级 00f18086
......@@ -35,14 +35,14 @@
#define CPSR_MODE_USR 0x10
#define CPSR_MODE_MASK 0x1f
/// 读CP15的系统控制寄存器到 R0寄存器
STATIC INLINE UINT32 OsArmReadSctlr(VOID)
{
UINT32 val;
__asm__ volatile("mrc p15, 0, %0, c1,c0,0" : "=r"(val));
return val;
}
/// R0寄存器写入CP15的系统控制寄存器
STATIC INLINE VOID OsArmWriteSctlr(UINT32 val)
{
__asm__ volatile("mcr p15, 0, %0, c1,c0,0" ::"r"(val));
......
......@@ -82,7 +82,7 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/// 内存管理单元(英语:memory management unit,缩写为MMU),有时称作分页内存管理单元(英语:paged memory management unit,缩写为PMMU)。
typedef struct ArchMmu {//内存管理单元
#ifndef LOSCFG_PAGE_TABLE_FINE_LOCK
SPIN_LOCK_S lock; /**< arch mmu page table entry modification spin lock */
......
......@@ -104,7 +104,7 @@ extern "C" {
#define CP15_REG64(CRn, Op1) "p15, "#Op1", %0, %H0,"#CRn
//CP15 协处理器各寄存器信息
/*!
* Identification registers (c0) | c0 - 身份寄存器
* Identification registers (c0) | c0 - 身份寄存器 详见 鸿蒙内核源码分析(协处理器篇)
*/
#define MIDR CP15_REG(c0, 0, c0, 0) /*! Main ID Register | 主ID寄存器 */
#define MPIDR CP15_REG(c0, 0, c0, 5) /*! Multiprocessor Affinity Register | 多处理器关联寄存器给每个CPU制定一个逻辑地址*/
......
......@@ -69,26 +69,26 @@ extern "C" {
/* L1 descriptor type */
#define MMU_DESCRIPTOR_L1_TYPE_INVALID (0x0 << 0)
#define MMU_DESCRIPTOR_L1_TYPE_PAGE_TABLE (0x1 << 0)
#define MMU_DESCRIPTOR_L1_TYPE_SECTION (0x2 << 0)
#define MMU_DESCRIPTOR_L1_TYPE_PAGE_TABLE (0x1 << 0) ///< 一级条目类型按页分
#define MMU_DESCRIPTOR_L1_TYPE_SECTION (0x2 << 0) ///< 1MB 一级条目类型按段分
#define MMU_DESCRIPTOR_L1_TYPE_MASK (0x3 << 0)
/* L2 descriptor type */
#define MMU_DESCRIPTOR_L2_TYPE_INVALID (0x0 << 0)
#define MMU_DESCRIPTOR_L2_TYPE_LARGE_PAGE (0x1 << 0)
#define MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE (0x2 << 0)
#define MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE_XN (0x3 << 0)
#define MMU_DESCRIPTOR_L2_TYPE_LARGE_PAGE (0x1 << 0) ///< 64KB 二级条目类型按大页分
#define MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE (0x2 << 0) ///< 4KB 二级条目类型按小页分
#define MMU_DESCRIPTOR_L2_TYPE_SMALL_PAGE_XN (0x3 << 0) ///< 1KB 二级条目类型按极小页分
#define MMU_DESCRIPTOR_L2_TYPE_MASK (0x3 << 0)
#define MMU_DESCRIPTOR_IS_L1_SIZE_ALIGNED(x) IS_ALIGNED(x, MMU_DESCRIPTOR_L1_SMALL_SIZE)
#define MMU_DESCRIPTOR_L1_SMALL_SIZE 0x100000
#define MMU_DESCRIPTOR_L1_SMALL_SIZE 0x100000 // 1M 页表L1大小
#define MMU_DESCRIPTOR_L1_SMALL_MASK (MMU_DESCRIPTOR_L1_SMALL_SIZE - 1)
#define MMU_DESCRIPTOR_L1_SMALL_FRAME (~MMU_DESCRIPTOR_L1_SMALL_MASK)
#define MMU_DESCRIPTOR_L1_SMALL_SHIFT 20
#define MMU_DESCRIPTOR_L1_SMALL_SHIFT 20 //移动位数
#define MMU_DESCRIPTOR_L1_SECTION_ADDR(x) ((x) & MMU_DESCRIPTOR_L1_SMALL_FRAME)
#define MMU_DESCRIPTOR_L1_PAGE_TABLE_ADDR(x) ((x) & ~((1 << 10)-1))
#define MMU_DESCRIPTOR_L1_SMALL_L2_TABLES_PER_PAGE 4
#define MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS 0x4000U
#define MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS 0x4000U ///< 16Kb 小页页表条目(4096个页表项)
#define MMU_DESCRIPTOR_L1_SMALL_DOMAIN_MASK (~(0x0f << 5)) /* 4k page section domain mask */
#define MMU_DESCRIPTOR_L1_SMALL_DOMAIN_CLIENT (MMU_DESCRIPTOR_DOMAIN_CLIENT << 5)
......
......@@ -1058,12 +1058,12 @@ VOID LOS_ArchMmuContextSwitch(LosArchMmu *archMmu)
#ifdef LOSCFG_KERNEL_VM
/* from armv7a arm B3.10.4, we should do synchronization changes of ASID and TTBR. */
OsArmWriteContextidr(LOS_GetKVmSpace()->archMmu.asid);//这里先把asid切到内核空间的ID
ISB;
ISB; //指令必须同步 ,清楚流水线中未执行指令
#endif
OsArmWriteTtbr0(ttbr);//通过r0寄存器将进程页面基址写入TTB
ISB;
ISB; //指令必须同步
OsArmWriteTtbcr(ttbcr);//写入TTB状态位
ISB;
ISB; //指令必须同步
#ifdef LOSCFG_KERNEL_VM
if (archMmu) {
OsArmWriteContextidr(archMmu->asid);//通过R0寄存器写入进程标识符至C13寄存器
......
......@@ -288,10 +288,8 @@ LosVmPage *OsVmPaddrToPage(paddr_t paddr)
VOID *OsVmPageToVaddr(LosVmPage *page)//
{
VADDR_T vaddr;
vaddr = KERNEL_ASPACE_BASE + page->physAddr - SYS_MEM_BASE;//page->physAddr - SYS_MEM_BASE 得到物理地址的偏移量
//因在整个虚拟内存中内核空间和用户空间是通过地址隔离的,如此很巧妙的就把该物理页映射到了内核空间
//内核空间的vmPage是不会被置换的,因为是常驻内存,内核空间初始化mmu时就映射好了L1表
return (VOID *)(UINTPTR)vaddr;
vaddr = KERNEL_ASPACE_BASE + page->physAddr - SYS_MEM_BASE;//表示申请的物理地址在物理空间的偏移量等于映射的虚拟地址在内核空间的偏移量
return (VOID *)(UINTPTR)vaddr;//不需要存储映射关系,这简直就是神来之笔,拍案叫绝。@note_good 详见 鸿蒙内核源码分析(页表管理篇)
}
///通过虚拟地址找映射的物理页框
LosVmPage *OsVmVaddrToPage(VOID *ptr)
......
git add -A
git commit -m ' 页表部分注解 , 博客见于 鸿蒙内核源码分析(页表管理)
git commit -m ' cp15 协处理代码注解
百图画鸿蒙 + 百文说内核 + 百万注源码 => 挖透鸿蒙内核源码
鸿蒙研究站 | http://weharmonyos.com (国内)
| https://weharmony.github.io (国外)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册