CloudKiss 发表于 2025-8-30 14:51

RISC-V内核中的mtvec寄存器

<h1>RISC-V内核中的mtvec寄存器</h1>
<p>今天下午研究了一下沁恒CH32V317,要玩CH32V317也要使用WCH-Link。WCH-Link支持RISC-V模式和ARM模式。还是蛮高级的一件事。再来研究了一下RISC-V和ARM的一个显著区别——中断向量表的配置mtvec寄存器,其支持ARM的vector table模式。好吧!再多看看mtvec寄存器。</p>
<p>mtvec 寄存器是用来设置机器模式的异常向量基地址寄存器(Machine Mode Exception Vector Base Address Register)。这个寄存器决定了如何处理中断和异常。</p>
<p>寄存器概述</p>
<p>在 RISC-V 中,mtvec 寄存器是一个 CSR(Control and Status Register),其地址为 0x305。它有两个主要的配置模式:直接模式和向量模式。</p>
<p>直接模式</p>
<p>在直接模式下,mtvec 的最低位(bit 0)被设置为 0。在这种模式下,异常向量基地址的低两位被忽略,因此实际的基地址是对齐到4字节边界的。例如,如果 mtvec 被设置为 0x80000000,实际的异常处理代码起始地址会是 0x80000000。</p>
<p>向量模式</p>
<p>在向量模式下,mtvec 的最低位被设置为 1。在这种模式下,异常向量基地址的低两位用来决定是使用 4 字节对齐的异常处理代码还是使用 16 字节对齐的异常处理代码。例如,如果 mtvec 被设置为 0x80000001,则实际的异常处理代码起始地址会是 0x80000000(4字节对齐),如果是 0x80000003,则可能是 0x80000010(16字节对齐)。</p>
<p>如何设置 mtvec</p>
<p>在汇编语言中,你可以使用 csrrw, csrrs, csrrc, 或 csrrwi, csrrsi, csrrci 指令来操作 mtvec 寄存器。例如,要将 mtvec 设置为向量模式下的 0x80000010(16字节对齐),你可以使用以下指令:</p>
<pre><code class="language-assembly">li t0, 0x80000013# Load the value into a register
csrw mtvec, t0   # Write the value to mtvec
</code></pre>
<p>或者,如果你只想设置基地址而不改变模式位(比如设置为直接模式下的 0x80000024):</p>
<pre><code class="language-assembly">li t1, 0x80000024# Load the base address into a register
csrw mtvec, t1   # Write the base address to mtvec (direct mode, mode bit is 0)
</code></pre>
<p>注意事项</p>
<p>确保异常处理代码在指定的内存地址处正确对齐。</p>
<p>在多核处理器中,通常每个核心的 mtvec 可以独立设置,以便每个核心可以有不同的异常处理代码。</p>
<p>在启动代码或操作系统初始化时设置 mtvec 是非常重要的,以确保系统能够正确响应异常和中断。</p>
<p>通过正确配置和使用 mtvec,你可以有效地管理和响应 RISC-V 系统中的异常和中断。</p>
<p>总结</p>
<p>学习之后,可以看到沁恒在mtvec寄存器上面应该融入了自己想法。将其扩展之后,更加适合现场应用。</p>

快乐制造机 发表于 2025-9-1 22:54

通过修改 mtvec 寄存器的值,可动态切换中断向量表

魔法森林精灵 发表于 2025-9-3 20:40

在向量模式下,除标准 4 字节和 16 字节对齐支持外,沁恒可能针对嵌入式场景优化了对齐粒度适配,允许根据异常处理代码长度动态调整(如 8 字节对齐)

逆鳞风暴 发表于 2025-9-3 22:38

向量表必须4字节对齐,编译器加.align 2

CloudKiss 发表于 2025-9-6 10:49

逆鳞风暴 发表于 2025-9-3 22:38
向量表必须4字节对齐,编译器加.align 2

现在的编译器是不是都会4字节对齐?!
感觉只要不特殊声明,其一定会4字节地址对齐。

OceanDepths 发表于 2025-9-7 13:51

向量模式应该是risv的独有特色了吧
页: [1]
查看完整版本: RISC-V内核中的mtvec寄存器