ARM架构中的中断状态寄存器解析与应用
ISR(Interrupt Status Register)是ARM架构中的一个系统寄存器,主要用于显示IRQ、FIQ中断和SError异常的挂起状态。简单来说,它就像一个"中断状态指示器",告诉你当前有哪些中断正在等待处理。
📝 简单理解:想象ISR是一个交通信号灯系统,红灯亮表示有中断需要处理,绿灯表示一切正常。
ISR是一个32位寄存器,但实际只使用了其中的几个关键位:
在ARM架构中,我们可以通过特定的指令来读取ISR寄存器的值:
MRC p15, 0, <Rt>, c12, c1, 0 ; 读取ISR寄存器到Rt
读取后,我们可以检查各个位的状态来判断中断情况:
// 示例:检查是否有IRQ中断挂起
MRC p15, 0, r0, c12, c1, 0 ; 读取ISR到r0
TST r0, #(1 << 7) ; 检查第7位(I位)
BNE handle_irq ; 如果有IRQ挂起,跳转到处理程序
⚠️ 注意:ISR寄存器是只读的,不能直接写入。它反映了当前系统的中断状态。
ISR寄存器在以下场景中特别有用:
在Linux内核中,ISR寄存器常用于中断处理和分析:
// 示例:Linux内核中检查中断状态
static inline u32 read_isr(void)
{
u32 isr;
asm volatile("mrc p15, 0, %0, c12, c1, 0" : "=r" (isr));
return isr;
}
void debug_interrupts(void)
{
u32 status = read_isr();
if (status & (1 << 7)) {
pr_info("IRQ interrupt pending\n");
}
if (status & (1 << 6)) {
pr_info("FIQ interrupt pending\n");
}
if (status & (1 << 8)) {
pr_info("SError exception pending\n");
}
}
在ATF中,ISR用于安全监控和异常处理:
// 示例:ATF中处理安全监控中断
void handle_secure_monitor(void)
{
uint32_t isr_value;
// 读取ISR寄存器
__asm__ volatile("mrc p15, 0, %0, c12, c1, 0" : "=r" (isr_value));
// 检查是否有SError异常
if (isr_value & (1 << 8)) {
// 处理系统错误异常
handle_serror();
}
// 其他处理...
}
在OP-TEE安全环境中,ISR用于监控非安全世界的中断行为:
// 示例:OP-TEE中监控非安全世界中断
TEE_Result monitor_ns_interrupts(void)
{
uint32_t isr_status;
// 读取ISR状态
__asm__ volatile("mrc p15, 0, %0, c12, c1, 0" : "=r" (isr_status));
// 记录非安全世界的中断活动
if (isr_status & (1 << 7)) {
LOG_INFO("NS world has pending IRQ");
}
if (isr_status & (1 << 6)) {
LOG_INFO("NS world has pending FIQ");
// FIQ在安全环境中需要特别关注
return TEE_ERROR_SECURITY;
}
return TEE_SUCCESS;
}
1. ISR寄存器只有在实现了FEAT_AA32EL1功能时才可用,否则访问会导致未定义指令异常
2. 在EL0异常级别无法访问ISR寄存器,尝试访问会导致异常
3. 在虚拟化环境中,ISR可能反映虚拟中断状态而非物理中断状态
4. SError异常的处理需要特别小心,可能导致系统不稳定