当前位置: 首页 > 科技观察

Loongarch架构介绍(三)——地址翻译

时间:2023-03-19 16:47:00 科技观察

了解更多开源请访问:开源基础软件社区https://ost.51cto.com前言本文为Loongarch架构介绍系列文章的第三篇。上面第一篇介绍了loonarch架构中的基本指令和用法,第二篇介绍了内存模型,原子指令和屏障指令的使用。虚拟内存系统是软硬件协同的经典案例。现在的主流架构和操作系统都已经支持虚拟内存机制。本文介绍loonarch虚拟内存系统的地址转换部分,主要包括地址转换方式、loonarch中的多级页表及相关配置。另外本文中的很多寄存器等资源都是特权资源,所以loongarch中的csr特权指令和特权等级也会作为背景知识介绍。1.特权级和csr特权指令虚拟内存相关寄存器等资源都是特权资源,所以在介绍loonarch虚拟内存相关机制之前,先介绍一下loonarch中的特权指令和特权级。1.权限级别loongarch架构中有4个权限级别(简称PLV),分别为PLV0-PLV3。其中,PLV0权限最高,是唯一可以使用特权指令,访问所有特权资源的特权级。而PLV3的权限最低。并且在大多数情况下,PLV1-PLV3这三个权限级别不能进行特权执行来访问特权资源。比如Linux系统loonarch架构相关的代码中,内核态在PLV0,用户态在PLV3。loongarch架构中有很多控制状态寄存器(controlstatusregisters,简称CSR),loongarch数据中一般用CSR.xxx来表示一个控制状态寄存器。cpu当前的特权级是由当前模式信息寄存器CSR.CRMD中的PLV字段决定的,即可以通过配置CSR.CRMD.PLV来设置当前的特权级。2.csr特权指令csr特权指令用于访问和配置控制状态寄存器,有以下几种:csrrd:读取CSR。例如csrrdrd,csr_num表示将csr_num对应的CSR的值写入通用寄存器rd。其中csr_num是loongarch中控制状态寄存器的编号,比如CSR.CRMD对应的编号就是0。比如下面的代码将CSR.CRMD的中间值读入临时寄存器t0:csrrdt0,0//CSR.CRMD对应的数字是0csrwr:写入CSR。例如csrwrrd,csr_num表示将通用寄存器rd中的值写入csr_num对应的CSR中,同时将csr_num对应的CSR中的旧值返回给rd。例如使用如下代码设置权限级别为PLV3:li.dt0,0xXXXXXXXXXXXXXX3//最低两位为3csrwrt0,0csrxchg:例如csrxchgrd,rj,csr_num表示通用寄存器中的值rj作为mask掩码,将rd的中值写入csr_num对应的CSR中1对应的位,CSR中其余位保持不变。同时将csr_num对应的csr中的旧值返回给rd。例如下面的代码也可以设置权限级别为PLV3:li.dt0,0x3csrxchgt0,t0,0//只将CSR.CRMD的最后两位设置为1。下图是对CSR.CRMD表中的PLV部分:2.地址空间loongarchLA32的虚拟地址空间大小为2^{32}232字节LA64的虚拟地址空间大小为2^{64}264字节大小loongarch中物理地址空间的大小为2^{PALEN}2PALEN字节,其中:在LA32中,PALEN为不超过36的正整数,通常为32,在LA64中,PALEN为不超过60的正整数。PALEN由具体的执行。软件可以通过CPUCFG指令读取PALENValue3.地址转换方式Loongarch的虚实地址转换机制首先由其地址转换方式决定。loongarch中有两种地址转换模式:直接地址转换模式:这种模式下,物理地址直接等于虚拟地址的低PALEN位,不足补0。相当于没有映射。映射地址转换模式:该模式分为两种模式:直接映射地址转换模式(简称直接映射模式):相当于线性映射。具体请参见下文中的描述。页表映射地址转换方式(简称页表映射方式):相当于分页机制。具体请参见下文中的描述。其中,直接地址转换模式和映射地址转换模式不能同时开启。但是,在映射地址转换模式下,直接映射模式和页表映射模式可以同时启用。在进行地址转换时,会优先使用直接映射方式。如果不能使用直接映射方式,则使用页表映射方式进行转换。1、地址转换模式的配置在loongarch中,通过控制寄存器CSR.CRMD配置地址转换模式:CSR中DA=1andPG=0。CRMD:直接地址转换模式CSR中DA=0andPG=1。CRMD:mappedaddresstranslation模式下其他DA和PG值的组合行为是未定义的。CSR.CRMD表中的DA和PG部分如下图所示:与上面权限级别的设置类似,地址转换模式的设置也使用了csrwr等指令。2、直接映射方式及其配置loongarch中的直接映射方式是一种线性映射方式,有点类似于分段。在loongarch中通过配置直接映射配置窗口寄存器来配置直接映射。直接映射配置窗口寄存器有4个,CSR.DMW0-CSR.DMW3,配置一个窗口相当于映射一个内存区域。其中CSR.DMW0和CSR.DMW1映射的内存区可以同时用于fetch和load/store操作,而CSR.DMW2和CSR.DMW3映射的内存区只用于load/store操作。下面介绍直接映射方式的配置和映射规则。(1)LA32下面以LA32,PALEN=32为例进行说明。LA32中直接映射配置窗口寄存器内容如下:其中:PLV0等字段为使能CSR.DMW寄存器,与访问权限级别相关。MAT域与内存一致性模型和内存访问类型有关。请参考上一篇文章PSEG域是配置的物理地址的高3位VSEG域是配置的虚拟地址的高3位例如下面的代码配置CSR.DMW0,映射虚拟地址0x80000000-0x9ffffffftothephysicaladdress0x0-0x1fffffff:li.wt0,0x80000011csrwrt0,0x180//0x180对应CSR.DMW0解释如下:0x80000011中VSEG为0b100,表示匹配的虚拟地址最高3位为0b100,即虚拟地址0x80000000-0x9fffffff0x80000011中,PSEG为0b0,表示匹配物理地址的最高3位为0b0,对应物理地址0x0-0x1fffffff(2)LA64下面使用LA64和以PALEN=48为例来说明。LA64中直接映射配置窗口寄存器内容如下:其中:PLV0等域,MAT域与LA32功能相同VSEG域与LA32类似,但有4位。映射到物理地址0x0-0xffffffffffff:li.dt0,0x9000000000000011csrwrt0,0x180//0x180对应CSR.DMW0解释如下:在0x9000000000000011中,VSEG为0x9,表示匹配虚拟地址的最高4位为0x9,即虚拟地址0x90000000-0x9000ffffffffffffPALEN=48,对应的物理地址为2^{48}248的整个地址范围,即0x0-0xffffffffffff3、页表映射方式及其配置(1)页表映射后modeenabled,pagetablebaseaddressisfirst需要配置页表基址。loongarch中可以同时存在两个pgd(页全局目录)基地址,地址存放在寄存器CSR.PGDL(低半地址空间全局目录基地址)和CSR.PGDH(高半地址空间全局目录)中基址),分别。对应下半地址空间和上半地址空间。CSR.PGDL和CSR.PGDH如下图所示:上图中GRLEN表示寄存器长度,VALEN表示虚拟地址长度。LA32中,GRLEN为32,VALEN为32;在LA64中,GRLEN是64位,VALEN是64位。下半部地址空间和上半部地址空间实际上分为两部分虚拟地址空间对半。如果虚拟地址的最高位为0,则表示在低半地址空间;如果为1,则表示在上半地址空间。两部分的地址由对应部分的pgd翻译,互不干扰。在Linux中,CSR.PGDH存放的是内核进程的pgd,CSR.PGDL存放的是用户进程的pgd。Loongarch相当于在硬件上隔离了内核空间和用户空间的页表。(2)页表分级在loongarch中可以自定义页表分级,使用页表前需要配置页表分级。loongarch中页表的具体分类是由寄存器CSR.PWCL和CSR.PWCH决定的。这两个寄存器分别控制下半部分和上半部分的页表分类。CSR.PWCH只存在于LA64中。注意:这里的lowhalf和highhalf是指寄存器分为两部分。CSR.PWCL和CSR.PWCH如下:下图是一个多级页表的例子:解释如下:其中xxbase表示该级在虚拟地址中的起始位置,xxwidth表示长度虚拟地址中的级别。以LA64为例,配置Dir4_base、PTbase等字段和Dir4_width、PTwidth等字段,相当于按照层次页表规则的解析方式指定虚拟地址。虚拟地址解析过程示例如下:首先,根据最高位选择CSR.PGDH或CSR。PGD??L中的pgd,即目录4的基地址,以虚拟地址中Dir4_base和Dir4_width指定范围内的值作为索引,在目录4中查找目录3对应的基地址。使用中的值以虚拟地址中Dir3_base和Dir3_width指定的范围为索引,在目录3中查找目录2对应的基地址。以虚拟地址中Dir2_base和Dir2_width指定的范围内的值为索引,在目录中查找directory2为目录1对应的基地址,以虚拟地址中Dir1_base和Dir1_width指定范围内的值作为索引。在目录1中查找末级页表对应的基地址以虚拟地址中PTbase和PTwidth指定范围的值作为索引,在末级页表中查找最终页表项。具体页表项信息见后续文章。(3)配置本节分析Linux源码中loonarch下页表的基地址和分类的配置。代码如下:staticvoidsetup_ptwalker(void){unsignedlongpwctl0,pwctl1;unsignedlongpgd_i=0,pgd_w=0;//Dir3_base和Dir3_widthunsignedlongpud_i=0,pud_w=0;//Dir2_base和Dir2_widthunsignedlong0,pmd_i=pmd_w=0;//Dir1_base和Dir1_widthunsignedlongpte_i=0,pte_w=0;//PTbase和PTwidth//PTEWidth为0,表示每个条目都是64bit//Dir4_base和Dir4_width没有设置pgd_i=PGDIR_SHIFT;pgd_w=PAGE_SHIFT-3;#ifCONFIG_PGTABLE_LEVELS>3pud_i=PUD_SHIFT;pud_w=PAGE_SHIFT-3;#endif#ifCONFIG_PGTABLE_LEVELS>2pmd_i=PMD_SHIFT;pmd_w=PAGE_SHIFT-3;#endifpte_i=PAGE_SHIFT|pte_w=PAGEptew_0=PAGE_SHIF<5|pmd_i<<10|pmd_w<<15|pud_i<<20|pud_w<<25;pwctl1=pgd_i|pgd_w<<6;//设置CSR.PWCL和CSR.PWCH,LOONGARCH_CSR_PWCTL0为CSR.PWCL//LOONGARCH_CSR_PWCTL1为CSR.PWCHcsr_write64(pwctl0,LOONGARCH_CSR_PWCTL0);csr_write64(pwctl1,LOONGARCH_CSR_PWCTL1);//DL设置CTR.PGD??H//CSR.PGDH中的Swapper_pg_dir是kernelemptyinter-pgd//CSR.PGDL为用户空间pgd,暂时设置为invalid_pg_dir,并分配csr_write64((long)swapper_pg_dir,LOONGARCH_CSR_PGDH);csr_write64((long)invalid_pg_dir,LOONGARCH_CSR_PGDL);...}本文的总结介绍了地址转换模式及相关配置。下一篇文章将继续介绍loonarch虚拟内存系统的其他部分。了解更多开源请访问:开源基础软件社区https://ost.51cto.com