asm/csr.h#

csr.h提供了读写RISC-V体系结构中的CSR寄存器(Control and Status)的函数

Author

Shihong Wang (jack4shihong@gamil.com)

Version

0.1

Date

2023-04-09

Copyright

Copyright Shihong Wang (c) 2023 with GNU Public License V3.0

Note

参考RISC-V架构手册:

  1. riscv/riscv-isa-manual

  2. riscv/riscv-isa-manual

Defines

PRIVILEGE_U#

用户态特权级

PRIVILEGE_S#

监管态特权级

PRIVILEGE_M#

机器态特权级

INTR_DS#

中断开启

INTR_EN#

中断关闭

MSTATUS_MPP_SHIFT#

MPP域在mstatus寄存器的偏移

MSTATUS_MPP#

MPP域选择子

MSTATUS_MPP_U#

MPP = 0b00, 中断发生前的特权级为U

MSTATUS_MPP_S#

MPP = 0b01, 中断发生前的特权级为S

MSTATUS_MPP_M#

MPP = 0b11, 中断发生前的特权级为M

MSTATUS_MPIE_SHIFT#

MPIE域在mstatus寄存器的偏移

MSTATUS_MPIE#

MPIE域选择子

MSTATUS_MPIE_DS#

MPIE = 0, 中断发生前中断关闭

MSTATUS_MPIE_EN#

MPIE = 1, 中断发生前中断开启

SSTATUS_SIE#

Supervisor Interrupt Enable

SSTATUS_SPIE#
SSTATUS_SPP#
SSTATUS_SUM#
SSTATUS_FS#
SSTATUS_XS#
TVEC_TRAP_DIRECT#

TVEC_TRAP_DIRECT宏表示mtvec寄存器处于直接模式

TVEC_TRAP_INDIRECT#

MTVEC_TRAP_INDIRECT宏表示mtvec寄存器处于间接模式

CAUSE_INTERRUPT_FLAG#

CAUSE_INTERRUPT_FLAG宏用于判断当前陷入是否为中断

CAUSE_EXCEPTION_FLAG#

CAUSE_EXCEPTION_FLAG宏用于判断当前陷入是否为异常

CAUSE_EXCEPTION_MISALIGNED_FETCH#
CAUSE_EXCEPTION_FETCH_ACCESS#
CAUSE_EXCEPTION_ILLEGAL_INSTRUCTION#
CAUSE_EXCEPTION_BREAKPOINT#
CAUSE_EXCEPTION_MISALIGNED_LOAD#
CAUSE_EXCEPTION_LOAD_ACCESS#
CAUSE_EXCEPTION_MISALIGNED_STORE#
CAUSE_EXCEPTION_STORE_ACCESS#
CAUSE_EXCEPTION_USER_ECALL#
CAUSE_EXCEPTION_SUPERVISOR_ECALL#
CAUSE_EXCEPTION_VIRTUAL_SUPERVISOR_ECALL#
CAUSE_EXCEPTION_MACHINE_ECALL#
CAUSE_EXCEPTION_FETCH_PAGE_FAULT#
CAUSE_EXCEPTION_LOAD_PAGE_FAULT#
CAUSE_EXCEPTION_STORE_PAGE_FAULT#
CAUSE_EXCEPTION_FETCH_GUEST_PAGE_FAULT#
CAUSE_EXCEPTION_LOAD_GUEST_PAGE_FAULT#
CAUSE_EXCEPTION_VIRTUAL_INST_FAULT#
CAUSE_EXCEPTION_STORE_GUEST_PAGE_FAULT#
CAUSE_INTERRUPT_U_SOFTWARE_INTERRUPT#
CAUSE_INTERRUPT_S_SOFTWARE_INTERRUPT#
CAUSE_INTERRUPT_M_SOFTWARE_INTERRUPT#
CAUSE_INTERRUPT_U_TIMER_INTERRUPT#
CAUSE_INTERRUPT_S_TIMER_INTERRUPT#
CAUSE_INTERRUPT_M_TIMER_INTERRUPT#
CAUSE_INTERRUPT_U_EXTERNAL_INTERRUPT#
CAUSE_INTERRUPT_S_EXTERNAL_INTERRUPT#
CAUSE_INTERRUPT_M_EXTERNAL_INTERRUPT#
MIP_U_SOFTWARE_INTERRUPT#
MIP_S_SOFTWARE_INTERRUPT#
MIP_M_SOFTWARE_INTERRUPT#
MIP_U_TIMER_INTERRUPT#
MIP_S_TIMER_INTERRUPT#
MIP_M_TIMER_INTERRUPT#
MIP_U_EXTERNAL_INTERRUPT#
MIP_S_EXTERNAL_INTERRUPT#
MIP_M_EXTERNAL_INTERRUPT#
MIE_U_SOFTWARE_INTERRUPT#
MIE_S_SOFTWARE_INTERRUPT#
MIE_M_SOFTWARE_INTERRUPT#
MIE_U_TIMER_INTERRUPT#
MIE_S_TIMER_INTERRUPT#
MIE_M_TIMER_INTERRUPT#
MIE_U_EXTERNAL_INTERRUPT#
MIE_S_EXTERNAL_INTERRUPT#
MIE_M_EXTERNAL_INTERRUPT#
SIE_S_SOFTWARE_INTERRUPT#
SIE_S_TIMER_INTERRUPT#
SIE_S_EXTERNAL_INTERRUPT#
SATP_MODE_SV39#
SATP_MODE_SV48#
SATP_MODE_SV57#
SATP_MODE_SV64#
SET_FIELD(origin, which, fieldval)#

SET_FIELD宏用于将originwhich所指定的field的值设置为fieldval

一个详细的例子origin = 0b1001_0001, which = 0b0011_0000, fieldval = 0b11则:

  • which & ~(which - 1) = 0b0001_0000

  • fieldval * (which & ~(which - 1)) = 0b0011_0000

  • origin & !(which) = 0b1011_0001

  • ... | ... = 0b1000_0000

Note

需要注意的点:

  • x & ~mask: 将x的非mask清0

  • x & ~(x - 1): 用于一个数的二进制表示中最右边的非零位(也称作最低位的1),并将其它位都置为0

  • 而后利用这个最右边的非零位表示需要左移多少位, 这里是用乘法实现的左移

  • 最后在和mask对应位清0之后的原值与就能得到最终需要的值

Parameters:
  • origin – 初始值

  • which – 设置的field

  • fieldvalfield将被设置的值

read_csr(csr)#

read_csr用于读取的csr寄存器的值并返回

Note

通常情况下,在内联汇编代码块的最后一条语句中将需要返回的值存储在一个特定的变量中,然后该变量将被作为代码块的返回值返回给调用者。在GCC扩展中,这个变量通常被命名为__v(两个下划线 + v),并且在代码块的最后一行写上__v;语句来表示将其作为返回值返回给调用者。

Note

写入到CSR寄存器的变量必须要存在通用寄存器中

Note

read_csr中使用#csr转为字符串, 而后利用C语言的字符串拼接得到最终的汇编语句

Parameters:
  • csr – 要读取的CSR寄存器名

Returns:

uint64_t 读取得到的csr寄存器的值

write_csr(csr, value)#

write_csr用于将csr寄存器的值设置为value

Parameters:
  • csr – 要设置的CSR寄存器名

  • value – 要设置的值

set_csr(csr, value)#

set_csr用于将csr寄存器的值value位的值设置为1

Parameters:
  • csr – 要设置的CSR寄存器名

  • value – 要设置的位

clear_csr(csr, value)#

clear_csr用于将csr寄存器的值value位的值设置为0

Parameters:
  • csr – 要设置的CSR寄存器名

  • value – 要设置的位