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 规范中所述,请参阅参考

名称

别名

用法

跨调用保留

$r0

$zero

常数零

未使用

$r1

$ra

返回地址

$r2

$tp

TLS/线程指针

未使用

$r3

$sp

堆栈指针

$r4-$r11

$a0-$a7

参数寄存器

$r4-$r5

$v0-$v1

返回值

$r12-$r20

$t0-$t8

临时寄存器

$r21

$u0

每个 CPU 基地址

未使用

$r22

$fp

帧指针

$r23-$r31

$s0-$s8

静态寄存器

注意

寄存器 $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 规范中描述的相同

名称

别名

用法

跨调用保留

$f0-$f7

$fa0-$fa7

参数寄存器

$f0-$f1

$fv0-$fv1

返回值

$f8-$f23

$ft0-$ft15

临时寄存器

$f24-$f31

$fs0-$fs7

静态寄存器

注意

您可能在一些旧代码中看到 $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. 指令列表

为简洁起见,此处仅列出指令名称(助记符); 请参阅参考资料以了解详细信息。

  1. 算术指令

    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
    
  2. 位移指令

    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
    
  3. 位操作指令

    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
    
  4. 分支指令

    BEQ BNE BLT BGE BLTU BGEU BEQZ BNEZ B BL JIRL
    
  5. 加载/存储指令

    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
    
  6. 原子操作指令

    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
    
  7. 屏障指令

    IBAR DBAR
    
  8. 特殊指令

    SYSCALL BREAK CPUCFG NOP IDLE ERTN(ERET) DBCL(DBGCALL) RDTIMEL.W RDTIMEH.W RDTIME.D
    ASRTLE.D ASRTGT.D
    
  9. 特权指令

    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 的整个虚拟地址空间配置如下

名称

地址范围

属性

UVRANGE

0x00000000 - 0x7FFFFFFF

页映射,已缓存,PLV0~3

KPRANGE0

0x80000000 - 0x9FFFFFFF

直接映射,未缓存,PLV0

KPRANGE1

0xA0000000 - 0xBFFFFFFF

直接映射,已缓存,PLV0

KVRANGE

0xC0000000 - 0xFFFFFFFF

页映射,已缓存,PLV0

用户模式 (PLV3) 只能访问 UVRANGE。 对于直接映射的 KPRANGE0 和 KPRANGE1,PA 等于 VA,并清除位 30~31。 例如,未缓存的直接映射 VA 0x00001000 是 0x80001000,而缓存的直接映射 VA 0x00001000 是 0xA0001000。

默认情况下,LA64 的整个虚拟地址空间配置如下

名称

地址范围

属性

XUVRANGE

0x0000000000000000 - 0x3FFFFFFFFFFFFFFF

页映射,已缓存,PLV0~3

XSPRANGE

0x4000000000000000 - 0x7FFFFFFFFFFFFFFF

直接映射,已缓存/未缓存,PLV0

XKPRANGE

0x8000000000000000 - 0xBFFFFFFFFFFFFFFF

直接映射,已缓存/未缓存,PLV0

XKVRANGE

0xC000000000000000 - 0xFFFFFFFFFFFFFFFF

页映射,已缓存,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 内核存储库