Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

文档改进:添加对龙芯架构实验的相关文档 #30

Open
Crypeter opened this issue May 25, 2024 · 3 comments
Open

文档改进:添加对龙芯架构实验的相关文档 #30

Crypeter opened this issue May 25, 2024 · 3 comments

Comments

@Crypeter
Copy link

PA实验文档中缺少对loongarch的支持,因此撰写补充文档:

龙芯手册(index.html)

交叉编译链安装(2.2.html#运行第一个c程序)

loongarch32r(手动安装到系统中)

  1. 下载已经编译好的龙芯工具链[loongson-gnu-toolchain](https://gitee.com/loongson-edu/la32r-toolchains/releases/download/v0.0.3/loongson-gnu-toolchain-8.3-x86_64-loongarch32r-linux-gnusf-v2.0.tar.xz)

  2. 解压后添加到系统路径中

#1.解压文件(请将文件名更换为你下载的文件名)
tar -xvf toolchain.tar.xz
#假设解压后的路径为~/Downloads/toolchain(请更换为你的解压后路径)
echo "export PATH=$PATH:~/Downloads/toolchain" >> ~/.bashrc
#使用其他shell请根据自己的shell完成环境变量的修改
source ~/.bashrc
  1. 检验工具链是否成功完成添加
loongarch32r-linux-gnusf-gcc -v

成功添加后得到的结果如下

Using built-in specs.
COLLECT_GCC=loongarch32r-linux-gnusf-gcc
COLLECT_LTO_WRAPPER=/home/public/ics2023/toolchains/loongson-gnu-toolchain-8.3-x86_64-loongarch32r-linux-gnusf-v2.0/bin/../libexec/gcc/loongarch32r-linux-gnusf/8.3.0/lto-wrapper
Target: loongarch32r-linux-gnusf
Configured with: /dev/shm/build_loongarch32r-linux-gnusf_x86_64_v2.0_20230903/src/target_gcc/configure --build=x86_64-redhat-linux --host=x86_64-linux-gnu --target=loongarch32r-linux-gnusf --prefix=/dev/shm/build_loongarch32r-linux-gnusf_x86_64_v2.0_20230903/build-canadian/root/usr --with-sysroot=/dev/shm/build_loongarch32r-linux-gnusf_x86_64_v2.0_20230903/build-canadian/root/usr/loongarch32r-linux-gnusf/sysroot --with-native-system-header-dir=/usr/include --with-gxx-include-dir=/dev/shm/build_loongarch32r-linux-gnusf_x86_64_v2.0_20230903/build-canadian/root/usr/loongarch32r-linux-gnusf/sysroot/usr/include/c++ --enable-languages=c,c++,fortran --with-build-sysroot= --disable-libstdcxx --disable-libgfortran --disable-libgomp --enable-libcc1 --enable-threads=posix --enable-__cxa_atexit --enable-initfini-array --enable-nls --disable-libmpx --disable-bootstrap --with-abi=ilp32s --enable-checking=release --with-pkgversion='LoongArch GNU toolchain LA32 v2.0 (20230903)'
Thread model: posix
gcc version 8.3.0 (LoongArch GNU toolchain LA32 v2.0 (20230903))

difftest安装(2.4.html#differential-testing)

loongarch32r:[QEMU](http://www.qemu.org/). QEMU是一个完整的全系统模拟器, 支持多种ISA. 但我们只能通过基于socket的GDB协议与QEMU进行通信来获取其状态, 通信开销较大. 为了运行龙芯的QEMU, 你还需要像安装工具链一样手动的安装它:

  1. 下载已经编译好的龙芯[QEMU-la32](https://gitee.com/loongson-edu/la32r-QEMU/releases/download/v0.0.2/la32r-QEMU-x86_64-ubuntu-22.04.tar)

  2. 解压后添加到系统路径中

#1.解压文件(请将文件名更换为你下载的文件名)
tar -xvf toolchain.tar.xz
#假设解压后的路径为~/Downloads/toolchain(请更换为你的解压后路径)
echo "export PATH=$PATH:~/Downloads/toolchain" >> ~/.bashrc
#使用其他shell请根据自己的shell完成环境变量的修改
source ~/.bashrc
  1. 检验工具链是否成功完成添加
qemu-system-loongarch32 -version

如果出现报错,则补充需要的动态链接库

sudo apt install libcapstone-dev
sudo apt install libvdeplug-dev

成功安装的输出如下

QEMU emulator version 6.2.50
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
  1. 如果你在2024/5/15 之前获取nemu的代码, 请获取新版代码:
cd nemu
git pull origin master

或者手动修改代码:

@@ -29,6 +29,9 @@
29 29   #elif defined(CONFIG_ISA_x86)
30 30   #define ISA_QEMU_BIN "qemu-system-i386"
31 31   #define ISA_QEMU_ARGS
   32 + #elif defined(CONFIG_ISA_loongarch32r)
   33 + #define ISA_QEMU_BIN "qemu-system-loongarch32"
   34 + #define ISA_QEMU_ARGS "-M","ls3a5k32",
32 35   #else
33 36   #error Unsupport ISA
34 37   #endif
@@ -49,6 +52,9 @@ union isa_gdb_regs {
49 52      uint32_t eax, ecx, edx, ebx, esp, ebp, esi, edi;
50 53      uint32_t eip, eflags;
51 54      uint32_t cs, ss, ds, es, fs, gs;
   55  + #elif defined(CONFIG_ISA_loongarch32r)
   56  + uint32_t gpr[32];
   57  + uint32_t pc;
52 58.   #endif
53 59    };
54 60    struct {

异常处理相关(3.2.html中添加)

loongarch32

loongarch32提供syscall指令作为自陷指令,并提供一个EENTRY寄存器来存放入口地址,为了保存程序当前的状态,loongarch32提供一些特殊的系统寄存器,叫控制状态寄存器,在PA中,我们只使用如下如下4个CSR寄存器:

  • CRMD寄存器 - 存放当前模式信息

  • PRMD寄存器 - 存放异常前模式信息

  • ESTAT寄存器 - 存放处理器的状态

  • ERA寄存器 - 异常的返回地址

loongarch32触发异常后硬件的响应过程如下:

  1. 将 CRMD 的 PLV、IE 分别存到 PRMD 的 PPLV、PIE 中,然后将CRMD的PLV置为 0,IE 置为 0;

  2. 将当前 PC 值记录到 CSR.ERA 中

  3. 跳转到异常入口地址

loongarch32通过retn指令从异常处理过程中返回,它将将 PRMD 中的 PPLV、PIE 值恢复到 CRMD 的 PLV、IE 中,并根据ERA寄存器恢复PC

@sashimi-yzh
Copy link
Contributor

目前还没打算正式支持LA32,这个issue就先留在这里给有需要的同学参考。

@Crypeter
Copy link
Author

Crypeter commented Aug 10, 2024

栈切换相关(4.3 html中添加)

loongarch32

对于内核栈切换的实现来说,loongarch32是一种吸收了mips32和riscv32的优点的方式。根据loongarch ABI的约定,通用寄存器中的r21,同时内核拥有4个专门保存数据的系统寄存器save0 - save3,编译器不会把变量分配到这个通用寄存器r21,同时中断和异常也不会改写这些系统寄存器save0 - save3,因此我们可以做如下约定

  • 把概念上的ksp映射到save0寄存器
  • 把概念上的c->np映射到c->gpr[21]
  • 把概念上的c->sp映射到c->gpr[sp]

你只需要根据上述约定在CTE中添加少量代码, 就可以实现内核栈切换的功能了.

@Crypeter
Copy link
Author

系统调用方式

目前都通过 syscall 0 指令进行系统调用。
尽管当下内核并不检查指令字中的立即数域,我们仍然强烈建议保持其为零,
这是为了防止未来它被赋予其他语义而造成您的程序产生非预期结果。

系统调用号应被存放于寄存器 a7
如系统调用有参数,这些参数应如函数调用一般,从 a0a6 按顺序存放。
系统调用返回时, a0 存放返回值, t0-t8 则应被视作被破坏(clobbered);
其他寄存器的值都保持不变。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants