1. LoongArch 简介¶
LoongArch 是一种新的 RISC ISA,它有点像 MIPS 或 RISC-V。目前有 3 个变体:精简的 32 位版本 (LA32R)、标准的 32 位版本 (LA32S) 和 64 位版本 (LA64)。LoongArch 中定义了 4 个特权级别 (PLV):PLV0~PLV3,从高到低。内核在 PLV0 运行,而应用程序在 PLV3 运行。本文档介绍了 LoongArch 的寄存器、基本指令集、虚拟内存和其他一些主题。
1.1. 寄存器¶
LoongArch 寄存器包括通用寄存器 (GPR)、浮点寄存器 (FPR)、向量寄存器 (VR) 和特权模式 (PLV0) 下使用的控制状态寄存器 (CSR)。
1.1.1. GPRs¶
LoongArch 有 32 个 GPR($r0
~ $r31
);在 LA32 中每个都是 32 位宽,在 LA64 中是 64 位宽。$r0
硬连线为零,其他寄存器在架构上没有特殊之处。(除了 $r1
,它被硬连线为 BL 指令的链接寄存器。)
内核使用 LoongArch 寄存器约定的变体,如 LoongArch ELF psABI 规范中所述,请参阅参考。
名称 |
别名 |
用法 |
跨调用保留 |
---|---|---|---|
|
|
常数零 |
未使用 |
|
|
返回地址 |
否 |
|
|
TLS/线程指针 |
未使用 |
|
|
堆栈指针 |
是 |
|
|
参数寄存器 |
否 |
|
|
返回值 |
否 |
|
|
临时寄存器 |
否 |
|
|
每个 CPU 基地址 |
未使用 |
|
|
帧指针 |
是 |
|
|
静态寄存器 |
是 |
注意
寄存器 $r21
在 ELF psABI 中保留,但被 Linux 内核用于存储每个 CPU 基地址。它通常没有 ABI 名称,但在内核中称为 $u0
。您可能在一些旧代码中看到 $v0
或 $v1
,但它们分别是 $a0
和 $a1
的已弃用别名。
1.1.2. FPRs¶
当存在 FPU 时,LoongArch 有 32 个 FPR($f0
~ $f31
)。在 LA64 核心上,每个都是 64 位宽。
浮点寄存器约定与 LoongArch ELF psABI 规范中描述的相同
名称 |
别名 |
用法 |
跨调用保留 |
---|---|---|---|
|
|
参数寄存器 |
否 |
|
|
返回值 |
否 |
|
|
临时寄存器 |
否 |
|
|
静态寄存器 |
是 |
注意
您可能在一些旧代码中看到 $fv0
或 $fv1
,但它们分别是 $fa0
和 $fa1
的已弃用别名。
1.1.3. VRs¶
目前 LoongArch 有两个向量扩展
LSX (Loongson SIMD eXtension),具有 128 位向量,
LASX (Loongson Advanced SIMD eXtension),具有 256 位向量。
LSX 带来了 $v0
~ $v31
,而 LASX 带来了 $x0
~ $x31
作为向量寄存器。
VR 与 FPR 重叠:例如,在实现 LSX 和 LASX 的核心上,$x0
的较低 128 位与 $v0
共享,而 $v0
的较低 64 位与 $f0
共享;其他所有 VR 也是如此。
1.1.4. CSRs¶
CSR 只能从特权模式 (PLV0) 访问
地址 |
全名 |
缩写名称 |
---|---|---|
0x0 |
当前模式信息 |
CRMD |
0x1 |
预异常模式信息 |
PRMD |
0x2 |
扩展单元启用 |
EUEN |
0x3 |
杂项控制 |
MISC |
0x4 |
异常配置 |
ECFG |
0x5 |
异常状态 |
ESTAT |
0x6 |
异常返回地址 |
ERA |
0x7 |
错误(故障)虚拟地址 |
BADV |
0x8 |
错误(故障)指令字 |
BADI |
0xC |
异常入口点地址 |
EENTRY |
0x10 |
TLB 索引 |
TLBIDX |
0x11 |
TLB 条目高位 |
TLBEHI |
0x12 |
TLB 条目低位 0 |
TLBELO0 |
0x13 |
TLB 条目低位 1 |
TLBELO1 |
0x18 |
地址空间标识符 |
ASID |
0x19 |
低半地址空间的页面全局目录地址 |
PGDL |
0x1A |
高半地址空间的页面全局目录地址 |
PGDH |
0x1B |
页面全局目录地址 |
PGD |
0x1C |
低半地址空间的页面遍历控制 |
PWCL |
0x1D |
高半地址空间的页面遍历控制 |
PWCH |
0x1E |
STLB 页面大小 |
STLBPS |
0x1F |
精简虚拟地址配置 |
RVACFG |
0x20 |
CPU 标识符 |
CPUID |
0x21 |
特权资源配置 1 |
PRCFG1 |
0x22 |
特权资源配置 2 |
PRCFG2 |
0x23 |
特权资源配置 3 |
PRCFG3 |
0x30+n (0≤n≤15) |
保存的数据寄存器 |
SAVEn |
0x40 |
计时器标识符 |
TID |
0x41 |
计时器配置 |
TCFG |
0x42 |
计时器值 |
TVAL |
0x43 |
计时器计数补偿 |
CNTC |
0x44 |
计时器中断清除 |
TICLR |
0x60 |
LLBit 控制 |
LLBCTL |
0x80 |
特定于实现的控制 1 |
IMPCTL1 |
0x81 |
特定于实现的控制 2 |
IMPCTL2 |
0x88 |
TLB 重填异常入口地址 |
TLBRENTRY |
0x89 |
TLB 重填异常 BAD(故障)虚拟地址 |
TLBRBADV |
0x8A |
TLB 重填异常返回地址 |
TLBRERA |
0x8B |
TLB 重填异常保存的数据寄存器 |
TLBRSAVE |
0x8C |
TLB 重填异常入口低位 0 |
TLBRELO0 |
0x8D |
TLB 重填异常入口低位 1 |
TLBRELO1 |
0x8E |
TLB 重填异常入口高位 |
TLBEHI |
0x8F |
TLB 重填异常前模式信息 |
TLBRPRMD |
0x90 |
机器错误控制 |
MERRCTL |
0x91 |
机器错误信息 1 |
MERRINFO1 |
0x92 |
机器错误信息 2 |
MERRINFO2 |
0x93 |
机器错误异常入口地址 |
MERRENTRY |
0x94 |
机器错误异常返回地址 |
MERRERA |
0x95 |
机器错误异常保存的数据寄存器 |
MERRSAVE |
0x98 |
缓存标签 |
CTAG |
0x180+n (0≤n≤3) |
直接映射配置窗口 n |
DMWn |
0x200+2n (0≤n≤31) |
性能监视器配置 n |
PMCFGn |
0x201+2n (0≤n≤31) |
性能监视器总计数器 n |
PMCNTn |
0x300 |
内存加载/存储监视点总控制 |
MWPC |
0x301 |
内存加载/存储监视点总状态 |
MWPS |
0x310+8n (0≤n≤7) |
内存加载/存储监视点 n 配置 1 |
MWPnCFG1 |
0x311+8n (0≤n≤7) |
内存加载/存储监视点 n 配置 2 |
MWPnCFG2 |
0x312+8n (0≤n≤7) |
内存加载/存储监视点 n 配置 3 |
MWPnCFG3 |
0x313+8n (0≤n≤7) |
内存加载/存储监视点 n 配置 4 |
MWPnCFG4 |
0x380 |
指令获取监视点总控制 |
FWPC |
0x381 |
指令获取监视点总状态 |
FWPS |
0x390+8n (0≤n≤7) |
指令获取监视点 n 配置 1 |
FWPnCFG1 |
0x391+8n (0≤n≤7) |
指令获取监视点 n 配置 2 |
FWPnCFG2 |
0x392+8n (0≤n≤7) |
指令获取监视点 n 配置 3 |
FWPnCFG3 |
0x393+8n (0≤n≤7) |
指令获取监视点 n 配置 4 |
FWPnCFG4 |
0x500 |
调试寄存器 |
DBG |
0x501 |
调试异常返回地址 |
DERA |
0x502 |
调试异常保存的数据寄存器 |
DSAVE |
ERA, TLBRERA, MERRERA 和 DERA 有时也称为 EPC, TLBREPC, MERREPC 和 DEPC。
1.2. 基本指令集¶
1.2.1. 指令格式¶
龙架构指令宽度为 32 位,属于 9 种基本指令格式(以及它们的变体)
格式名称 |
组成 |
---|---|
2R |
操作码 + Rj + Rd |
3R |
操作码 + Rk + Rj + Rd |
4R |
操作码 + Ra + Rk + Rj + Rd |
2RI8 |
操作码 + I8 + Rj + Rd |
2RI12 |
操作码 + I12 + Rj + Rd |
2RI14 |
操作码 + I14 + Rj + Rd |
2RI16 |
操作码 + I16 + Rj + Rd |
1RI21 |
操作码 + I21L + Rj + I21H |
I26 |
操作码 + I26L + I26H |
Rd 是目标寄存器操作数,而 Rj、Rk 和 Ra(“a” 代表“additional”)是源寄存器操作数。 I8/I12/I14/I16/I21/I26 是各自宽度的立即操作数。较长的 I21 和 I26 存储在指令字中单独的较高和较低部分,用“L”和“H”后缀表示。
1.2.2. 指令列表¶
为简洁起见,此处仅列出指令名称(助记符); 请参阅参考资料以了解详细信息。
算术指令
ADD.W SUB.W ADDI.W ADD.D SUB.D ADDI.D SLT SLTU SLTI SLTUI AND OR NOR XOR ANDN ORN ANDI ORI XORI MUL.W MULH.W MULH.WU DIV.W DIV.WU MOD.W MOD.WU MUL.D MULH.D MULH.DU DIV.D DIV.DU MOD.D MOD.DU PCADDI PCADDU12I PCADDU18I LU12I.W LU32I.D LU52I.D ADDU16I.D
位移指令
SLL.W SRL.W SRA.W ROTR.W SLLI.W SRLI.W SRAI.W ROTRI.W SLL.D SRL.D SRA.D ROTR.D SLLI.D SRLI.D SRAI.D ROTRI.D
位操作指令
EXT.W.B EXT.W.H CLO.W CLO.D SLZ.W CLZ.D CTO.W CTO.D CTZ.W CTZ.D BYTEPICK.W BYTEPICK.D BSTRINS.W BSTRINS.D BSTRPICK.W BSTRPICK.D REVB.2H REVB.4H REVB.2W REVB.D REVH.2W REVH.D BITREV.4B BITREV.8B BITREV.W BITREV.D MASKEQZ MASKNEZ
分支指令
BEQ BNE BLT BGE BLTU BGEU BEQZ BNEZ B BL JIRL
加载/存储指令
LD.B LD.BU LD.H LD.HU LD.W LD.WU LD.D ST.B ST.H ST.W ST.D LDX.B LDX.BU LDX.H LDX.HU LDX.W LDX.WU LDX.D STX.B STX.H STX.W STX.D LDPTR.W LDPTR.D STPTR.W STPTR.D PRELD PRELDX
原子操作指令
LL.W SC.W LL.D SC.D AMSWAP.W AMSWAP.D AMADD.W AMADD.D AMAND.W AMAND.D AMOR.W AMOR.D AMXOR.W AMXOR.D AMMAX.W AMMAX.D AMMIN.W AMMIN.D
屏障指令
IBAR DBAR
特殊指令
SYSCALL BREAK CPUCFG NOP IDLE ERTN(ERET) DBCL(DBGCALL) RDTIMEL.W RDTIMEH.W RDTIME.D ASRTLE.D ASRTGT.D
特权指令
CSRRD CSRWR CSRXCHG IOCSRRD.B IOCSRRD.H IOCSRRD.W IOCSRRD.D IOCSRWR.B IOCSRWR.H IOCSRWR.W IOCSRWR.D CACOP TLBP(TLBSRCH) TLBRD TLBWR TLBFILL TLBCLR TLBFLUSH INVTLB LDDIR LDPTE
1.3. 虚拟内存¶
龙架构支持直接映射虚拟内存和页映射虚拟内存。
直接映射虚拟内存由 CSR.DMWn (n=0~3) 配置,它在虚拟地址 (VA) 和物理地址 (PA) 之间具有简单的关系
VA = PA + FixedOffset
页映射虚拟内存在 VA 和 PA 之间具有任意关系,记录在 TLB 和页表中。 龙架构的 TLB 包括一个全相联 MTLB(多页大小 TLB)和组相联 STLB(单页大小 TLB)。
默认情况下,LA32 的整个虚拟地址空间配置如下
名称 |
地址范围 |
属性 |
---|---|---|
|
|
页映射,已缓存,PLV0~3 |
|
|
直接映射,未缓存,PLV0 |
|
|
直接映射,已缓存,PLV0 |
|
|
页映射,已缓存,PLV0 |
用户模式 (PLV3) 只能访问 UVRANGE。 对于直接映射的 KPRANGE0 和 KPRANGE1,PA 等于 VA,并清除位 30~31。 例如,未缓存的直接映射 VA 0x00001000 是 0x80001000,而缓存的直接映射 VA 0x00001000 是 0xA0001000。
默认情况下,LA64 的整个虚拟地址空间配置如下
名称 |
地址范围 |
属性 |
---|---|---|
|
|
页映射,已缓存,PLV0~3 |
|
|
直接映射,已缓存/未缓存,PLV0 |
|
|
直接映射,已缓存/未缓存,PLV0 |
|
|
页映射,已缓存,PLV0 |
用户模式 (PLV3) 只能访问 XUVRANGE。 对于直接映射的 XSPRANGE 和 XKPRANGE,PA 等于 VA,并清除位 60~63,缓存属性由 VA 中的位 60~61 配置:0 表示强排序的未缓存,1 表示一致性缓存,2 表示弱排序的未缓存。
目前,我们只使用 XKPRANGE 进行直接映射,XSPRANGE 保留。
将其付诸实践:0x00000000_00001000 的强排序未缓存直接映射 VA(在 XKPRANGE 中)是 0x80000000_00001000,0x00000000_00001000 的一致性缓存直接映射 VA(在 XKPRANGE 中)是 0x90000000_00001000,以及 0x00000000_00001000 的弱排序未缓存直接映射 VA(在 XKPRANGE 中)是 0xA0000000_00001000。
1.4. 龙芯和龙架构的关系¶
龙架构是一种 RISC ISA,它不同于任何其他现有的 ISA,而龙芯是一个处理器系列。 龙芯包括 3 个系列:龙芯 1 是 32 位处理器系列,龙芯 2 是低端 64 位处理器系列,龙芯 3 是高端 64 位处理器系列。 旧的龙芯基于 MIPS,而新的龙芯基于龙架构。 以龙芯 3 为例:龙芯 3A1000/3B1500/3A2000/3A3000/3A4000 与 MIPS 兼容,而龙芯 3A5000(以及未来的版本)均基于龙架构。
1.5. 参考资料¶
龙芯科技股份有限公司官方网站
龙芯和龙架构的开发者网站(软件和文档)
龙架构 ISA 文档
龙架构 ELF psABI 文档
龙芯和龙架构的 Linux 内核存储库