我需要在裸金属RISC-V系统上实现一个机器模式陷阱处理程序。陷阱处理程序应该使用独立于主程序的堆栈区域。如果在汇编中实现,我理解其基本流程:
-
输入陷阱处理程序
-
写
sp
使用陷阱堆栈指针(保存在
mscratch
例如)
-
将上下文保存在堆栈上(寄存器x1-x31)
-
做事
-
从堆栈中恢复上下文
-
使用原始堆栈指针写入sp
-
返回
mret
现在,我正试图尽量减少汇编代码的使用
GCC's RISC-V specific function attribute
:
void f (void) __attribute__ ((interrupt ("machine")));
看起来它能够自动完成上面的所有步骤
除了
第2步和第6步,即交换堆栈。
问题是,GCC中是否有一种方法/技巧可以生成一个函数,即中断处理程序,用于上下文保存,或者用于堆栈帧分配的通用函数使用不同的堆栈?
(注:我知道
naked
属性,但这里的想法是受益于序言/尾声的自动生成
interrupt
属性正在提供)
UPD:
事实上,我发现在最近的SiFive特定GCC中,他们引入了额外的属性选项:
void f (void) __attribute__ ((interrupt ("SiFive-CLIC-stack-swap")));
从他们的
GitHub repo
但它看起来只是针对机器陷阱。我正在寻找一个解决方案,同样适用于监管陷阱。