龙芯KVM分析中,顺便看了看龙芯3A2000的手册,记录当笔记。

总体上跟Mips标准架构差异不大,仅记录特别的需要注意的点。(内容大部分摘自龙芯手册)

内存管理

地址空间

地址空间是指某一特定寻址模式下所能覆盖的所有地址范围。MIPS64 架构中包含一个 64 位地址空间以及一个 32 位地址空间,后者同时映射为前者的一个子集。

段及段大小(SEGBITS)

段是地址空间的一个子集,同一段内的地址空间具有一致的映射方式和访问属性。以 MIPS64 规范的定义为例,其 32 位地址空间被划分为一系列大小为 2 29 或 2 31 字节的段,其 64 位地址空间理论上可以支持不超过 2^62 字节大小的段。实际中无需实现这么大的段,实际实现的段大小(SEGBITS)决定了地址空间被划分为一系列大小为 2^SEGBITS 字节的段。

物理地址大小(PABITS)

物理地址大小(PABITS)决定了处理器实际支持的物理地址空间的大小为 2^PABITS 字节。

映射地址(Mapped Address)与非映射地址(Unmapped Address)

“映射地址(Mapped Address)”的地址是指该地址需要通过 TLB 进行虚实地址转换。“非映射地址(Unmapped Address)”是指该地址不需要经过 TLB 进行虚实地址转换,虚地址被直接线性映射至物理地址的最低部分。

基于 TLB 的虚实地址映射

TLB 是处理器中存放操作系统页表信息的一个临时缓存,用于加速映射地址空间上取指及访存操作的 虚实地址转换过程。

TLB 层次结构

GS464E 中实现了两级 TLB。第一级 TLB 是取指和访存部件中各自包含的一个容量较小的全相联查找的 TLB,分别称之为 ITLB 和 DTLB;第二级 TLB 容量较大,包含一个全相联和一个八路组相联的查找表,称之为 JTLB。

JTLB 的所有内容软件可见,表项的装填替换由软件管理。ITLB 和 DTLB 的所有内容软件不可见,其表项的装填替换由硬件维护。在处理器运行时,DTLB 与 JTLB 中存放的页表内容始终为包含关系,该包含关系由硬件自动维护。但是 ITLB 与 JTLB 各自存放的内容无明确包含与互斥关系,也就是说,软件无法通过维护 JTLB 中的内容来确定 ITLB 中存放的信息。在一般运行过程中,ITLB 与 JTLB 中存放信息不维持包含关系对于软件的正确性没有影响。但是,如果操作系统试图修改一项已经存在的页表信息,并且该页表项对应的地址空间上存放有程序代码,那么系统软件必须对 Diag.ITLB 位写 1 来显式地清空 ITLB 的所有内容,以保证 ITLB 中一定不再有该页表项修改前的内容。

JTLB 组织结构

从软件的角度看,JTLB 包含一张全相联查找表和一张多路组相联的查找表,前者因支持不同表项采用不同的页大小而称为可变页大小TLB(Variable-Page-Size TLB),简称 VTLB;后者在同一时刻所有表项页大小相同,称为固定页大小 TLB(Fixed-Page-Size TLB),简称 FTLB。在虚实地址转换过程中,VTLB 和 FTLB同时查找。相应地,软件需保证 VTLB 和 FTLB 不会出现多项命中的情况,否则处理器行为将不可知。VTLB 的组织形式及操作方式与 MIPS 传统的全相联 TLB 非常相似,在 GS464E 中为 64 项。如果GSConfig.VTLBOnly 位置为 1,则禁用 FTLB 的所有功能,仅保留 VTLB。该配置下,龙芯 3A1000 芯片上已有操作系统中关于 TLB 管理部分的无需修改即可在龙芯 3A2000 芯片上正确执行。

FTLB 组织为 8 路组相联结构,每一路包含 128 项,共 1024 项,每一项保存 2 个页表信息,因此最多可存放 2048 个页表信息。在进行查找的过程中,硬件将提取虚地址的[(17+Config4.FTLBPageSize) :(11+Config4.FTLBPageSize)]位作为索引信息,对各路中相同索引位置项的内容进行比较,以决定是否有匹配项。

JTLB 表项

VTLB 和 FTLB 表项的格式基本一致,区别仅在与 VTLB 每个表项均包含 PageMask 信息,而 FTLB 因为是同一页大小故不保持 PageMask 信息。每一个 JTLB 表项包含两个部分:比较部分和物理转换部分。

表项的比较部分包括:

  • 页表无效位(EHINV)。当该位为 1 时,该页表项不参与查找匹配。
  • 地址空间号(MID)。用以标识该页表项地址处于哪个地址空间。
  • 虚拟处理器号及其掩码(VPID, VPMSK)。VPID&VPMSK 是该页表项地址所处的虚拟处理器号。
  • 虚地址区域标识(R)和虚页号(VPN2)。在 MIPS 架构中,每一个页表项存放了相邻的一对奇偶相邻页表信息,所以 TLB 页表项中存放虚页号的是系统中虚页号/2 的内容,即虚页号的最低位不予存放,仅用于查找时决定是选择奇数号页还是偶数号页的物理转换信息。
  • 地址空间标识(ASID)和全局标志位(G)。地址空间标识用于区分不同进程中的同样的虚地址,操作系统为每个进程分配唯一的 ASID,TLB 在进行查找时除地址信息外一致外,还需要比对 ASID 信息。当操作系统需要在所有进程间共享同一虚拟地址时,可以设置 TLB 页表项中的 G 位,G 位置1 后 TLB 查找时将不再进行 ASID 是否一致的检查。
  • 地址页掩码(Mask)。地址掩码用于控制该页表项中存放的页表大小。GS464E 支持 4KB 至 1GB,以 4 的倍数递增的页大小。对于 VTLB,每一项都存有 Mask 信息,因此不同项可以对应不同的页大小。对于 FTLB,所有项采用统一的 Mask 信息,由 Config4.FTLBPageSize 域决定。

表项的物理转换部分存有一对奇偶相邻页表的物理转换信息,每一个页的转换信息包括:

  • 物理页号(PFNX & PFN)。
  • 有效位(V)。
  • 脏位(D)。页是否可写的控制位,而不是页是否被写入了脏数据的状态位。
  • 读禁止位(RI)。
  • 执行禁止位(XI)。
  • 内核执行保护位(K),仅在 64 位模式下有意义,32 位模式下请将 GSConfig.KE 恒置为 0 以保证K位不产生效果。
  • Cache 属性(C)。

TLB 的软件管理

GS464E 仍沿袭了传统 MIPS 架构对于 TLB 的管理方式,即采用软件主导、软硬件相结合的方式管理TLB。MIPS 规范 release 5 及之后的版本中所新增的硬件页表遍历查找(Hardware Page Table Walking)功能在 GS464E 中不予实现。GS464E 在 MIPS 规范基础之上提供了一套专门用于页表遍历查找的特权访存指令用于加速这一过程。

TLB 进行虚实地址转换过程由硬件自动完成,但是当 TLB 中没有匹配项,或者尽管匹配但页表项无效或访问非法时,就需要触发例外,交由操作系统内核或其它监管程序,由软件进一步处理,对 TLB 的内容进行维护,或对程序执行的合法性做最后裁定。GS464E 中与 TLB 管理相关的例外(Exception, 异常)有:

  1. TLB 重填例外
  2. XTLB 重填例外
  3. TLB 无效例外
  4. TLB 修改例外
  5. 不可执行例外
  6. 不可读取例外

相关特权指令

  • TLBP 在 TLB 中搜索匹配项
  • TLBR 读索引的 TLB 表项
  • TLBWI 写索引的 TLB 表项
  • TLBWR 写随机的 TLB 表项
  • TLBINVF 将所有 TLB 表项无效
  • LWDIR 32 位模式下页表目录项装载指令
  • LWPTE 32 位模式下页表页表项装载指令
  • LDDIR 64 位模式下页表目录项装载指令
  • LDPTE 64 位模式下页表页表项装载指令

VTLB 与 FTLB 采用统一的软硬件交互接口,即使用同一套 CP0 寄存器和同样的 TLB 特权指令。

TLB 初始化与清空

建议使用 TLBINVF 指令将 TLB 所有项无效的方式来初始化或清空 TLB。也可以利用 EntryHi 寄存器中的 EHINV 域,循环执行 TLBWI 指令将 TLB 中所有项逐一无效。

异常(例外)

例外入口向量位置

冷复位、软复位、不可屏蔽中断 无偏移,直接使用基址 各类 EJTAG 调试例外(ProbTrap=0) 无偏移,直接使用基址 各类 EJTAG 调试例外(ProbTrap=1) 无偏移,直接使用基址 TLB 重填例外(Status.EXL=0) 0x000 XTLB 重填例外(Status.EXL=0) 0x080 Cache 错例外 0x100 其它例外情况 0x180 中断(Cause.IV=0) 0x180 中断(IntCtl.VS=0 且 Cause.IV=1) 0x200 中断(Status.BEV=1 且 Cause.IV=1) 0x200 中断(Cause.IV=1 且 Status.BEV=0 且 IntCtl.VS!=0) 0X200 + (中断向量号 × (IntCtl.VS || 0b00000))

TLB 重填例外

32 位主机地址空间下,且 Root.Status.EXL=0,访存使用映射地址,该地址在 TLB 中查找无匹配项时触发 TLB 重填例外。请注意该情况区别于在 TLB 中找到了匹配项但是匹配页表项有效位为 0,后者对应的是TLB 无效例外。为了加速 TLB 重填这一频繁而关键例外的处理效率, TLB 重填例外采用单独的例外入口偏移值,因此该例外在 Root.Cause.ExcCode 域填入的例外编码与 XTLB 重填例外、TLB 无效例外不做区分。

该例外仅在根模式下处理。

控制寄存器 Cause 的 ExcCode 域:

  • 0x02 (TLBL):取指或读数据
  • 0x03 (TLBS):写数据

响应例外时的额外硬件状态更新:

  • BadVAddr 记录触发例外的虚地址。
  • Context BadVPN2域记录触发例外的虚地址的[31..13]位。
  • XContext ?
  • EntryHi VPN2 域记录触发例外的虚地址的[47..13]位;R 域记录触发例外的虚地址的[63..62]位;ASID 域记录触发该例外的操作所属进程的 ASID
  • Diag MID 域置为 0。

TLB 无效例外

当出现下列情况时触发 TLB 无效例外: 访存在主机地址空间下使用映射地址,该地址在 TLB 中找到了匹配项但是匹配页表项有效位为 0,触发该例外。

软件需要注意下面这种情况(类似于X86中的缺页异常?):当 Root.Status.EXL=1 时,访存所使用的映射地址在 TLB 中找不到匹配项时,所采用的例外入口偏移是普通例外入口偏移 (0x180),同时 Root.Cause.ExcCode 域填入的例外编码仍是TLBL (0x2)或 TLBS (0x3)。为了将这种情况与正常的 TLB 无效例外区分开来,只能由例外处理程序使用TLBP 指令,根据查找结果进行区分。

该例外仅在根模式下处理。

控制寄存器 Cause 的 ExcCode 域: 0x02 (TLBL):取指或读数据 0x03 (TLBS):写数据

TLB 修改例外

store 操作在主机地址空间下映射地址,该地址在 TLB 中找到了匹配且有效的项,但是该页表项的 D 位为 0(意味着该页不可写) ,触发 TLB 修改例外。

该例外仅在根模式下处理。

控制寄存器 Cause 的 ExcCode 域:

  • 0x01 (Mod)

系统调用例外

当执行 SYSCALL 指令时,触发系统调用例外。

该例外可在根模式和客模式下处理。

控制寄存器 Cause 的 ExcCode 域:

  • 0x08 (Sys)

处理器性能分析与优化

GS464E 的性能分析与优化工作主要通过硬件集成的性能计数器完成。性能计数器用于统计处理器内部某些事件的发生次数,是芯片硅后性能验证、编译器优化、软件性能调优工作的重要支撑。此外,由于这些性能计数器所记录某些事件的统计意义与芯片运行时的功耗有相关性,性能计数器还可以用来指导芯片的功耗管理。

GS464E 所采用的性能计数器包含两个部分:处理器核性能计数器和共享缓存性能计数器。