1. CSR概述
系统指令用于访问那些可能需要特权访问的系统功能,以I类指令格式编码。这可以分为两类:一类是原子性读-修改-写控制和状态寄存器(CSR)的指令,另一类是其他特权指令。
所有的CSR指令都会对CSR进行读——改——写操作。CSR指令中共有12位(20-31位)用来指示被“读改写”的是哪一个寄存器。
1.1 CSRRW
名称: 读后立即写控制状态寄存器
指令格式:
csrrw rd,csr,rs1
功能: 将指定的CSR寄存器中的值读出并赋值到目的寄存器rd中,然后将源寄存器rs1中的值写入该CSR寄存器。
示例:
csrrw x13,mie,x12 #将mie寄存器中的值读出并赋值给x13寄存器,然后将x12寄存器中的值按位或的结果写入mie寄存器。
1.2 CSRRS
名称: 读后置位控制状态寄存器
指令格式:
csrrs rd,csr,rs1
功能: 将指定的CSR寄存器中的值读出并赋值到目的寄存器rd中,然后将CSR寄存器中的值和寄存器rs1中的值按位或(bitwise OR)的结果写入CSR寄存器。这相当于将rs1中所有为1的位所对应的CSR中的位都置为1。
示例:
csrrs x13,mie,x12 #将mie寄存器中的值读出并赋值给x13寄存器,然后将mie寄存器中的值和x12寄存器中的值按位或的结果写入mie寄存器。
1.3 CSRRC
名称: 读后清除控制状态寄存器
指令格式:
csrrc rd,csr,rs1
功能: 将指定的CSR寄存器中的值读出并赋值到目的寄存器rd中,然后将CSR寄存器中的值和寄存器rs1中的值取反后按位与(bitwise AND NOT)的结果写入CSR寄存器。这相当于将rs1中所有为1的位所对应的CSR中的位都清零。
示例:
csrrc x13,mie,x12 #将mie寄存器中的值读出并赋值给x13寄存器,然后将mie寄存器中的值和x12寄存器中的值取反后按位与的结果写入mie寄存器。
1.4 CSRRWI
名称: 立即数读后写控制状态寄存器
指令格式:
csrrwi rd, csr, uimm
功能: 将指定的CSR寄存器中的值读出并赋值到目的寄存器rd中,然后将一个5位的无符号立即数(uimm)扩展为32位后写入该CSR寄存器。
示例:
csrrwi x13,mie,5 #将mie寄存器中的值读出并赋值给x13寄存器,然后将5(扩展为32位的0000_0005)写入mie寄存器。
1.5 CSRRSI
名称: 立即数读后设置控制状态寄存器
指令格式:
csrrsi rd, csr, uimm
功能: 功能类似与CSRRS,但不同之处在于源值是一个立即数而不是寄存器值。
示例:
csrrsi t0, mstatus, 0b0000_0100 // 立即数为0b0000_0100,表示要将第3位设置为1
1.6 CSRRCI
名称: 立即数读后清除控制状态寄存器
指令格式:
csrrci rd, csr, uimm
功能: 与功能类似CSRRC,但不同之处在于源值是一个立即数而不是寄存器值。
示例:
csrrci t1, mstatus, 0b0000_0010 // 立即数为0b0000_0010,表示要清除第2位
2. 示例
#include "type.h" //包含类型定义,如uint64_t等。
#include "printk.h" //包含printk函数的声明,该函数用于在内核或裸机环境中打印信息。
#include "asm/csr.h" //包含CSR(控制状态寄存器)相关操作的声明。这包括读取和写入CSR寄存器的函数或宏。
uint64_t read_sscratch(void); //声明一个函数,用于读取sscratch寄存器的值。
void write_sscratch(uint64_t sscratch); //声明一个函数,用于将指定的值写入sscratch寄存器。
int main(void)
{
printk("sscratch value: 0x%llx\n", read_sscratch()); //printk打印当前sscratch寄存器的值。这通过调用read_sscratch()函数实现。
write_sscratch(0x1234567812345678); //特定的值写入sscratch寄存器。
printk("sscratch value: 0x%llx\n", read_sscratch()); //重新打印sscratch寄存器的值,以验证写入是否成功。
while (1) {}
return 0;
}
2.1 进入示例
下载解压并进入示例目录
2.2 编译
make
2.3 运行
make run
运行LOG如下
qemu-system-riscv64 -nographic -machine virt -m 128M -bios m_mode.bin -device loader,file=s_mode.bin,addr=0x80200000 -kernel s_mode.elf
_____ ____ _____
/ ____| _ \_ _|
| (___ | |_) || |
\ \___ \| _ < | |
____) | |_) || |_
|_|_____/|____/_____|
sscratch value: 0x0
sscratch value: 0x1234567812345678
详见请参考文档:实验环境搭建。