问题描述
我正在研究一个裸机中断控制器,GIC 版本 3。底层架构是 Virt,带有 QEMU,和一个 cpu Arm Cortex-72,aarch64:
qemu-system-aarch64 -machine virt,gic-version=3 -cpu cortex-a72 -nographic -kernel kernel.elf
根据ARMv8-A guide,Interrupt Group 1 Enable register,寄存器0
的位ICC_IGRPEN1_EL1
负责IRQ的激活。这是其中的摘录:
我指定我在非安全模式下工作。
我想从时序上下文生成一个 IRQ。计时器运行良好,但由于任何原因,即使 0
的 ICC_IGRPEN1_EL1
位设置为 1,也未捕获 IRQ。
由于我使用了多个标头,因此无法为您提供最小示例。我没有办法,如果你能建议我怎么做,请做。不过,我已经尽力提出了一个明确的问题,所以我真的希望你能帮上忙。
void timer_init(void)
{
uint64_t ticks,current_cnt;
// disable the timer
disable_cntv();
//read system frequency
cntfrq = raw_read_cntfrq_el0();
// Next timer IRQ is after 3 sec(s).
ticks = 3 * cntfrq;
// Get value of the current timer
current_cnt = raw_read_cntvct_el0();
// Set the interrupt in Current Time + TimerTick
raw_write_cntv_cval_el0(current_cnt + ticks);
// Enable the timer
enable_cntv();
// Enable IRQ
enable_irqs();
while(1){
wfi();
}
}
函数 enable_irqs
的定义如下:
void enable_irqs(void) {
set_gic_gicc_igrpen1_el1(0x1);
}
反过来,函数 set_gic_gicc_igrpen1_el1
是:
void set_gic_gicc_igrpen1_el1(uint64_t value)
{
__asm__ __volatile__("msr s3_0_c12_c12_7,%0" : : "r" (value));
}
我使用 gdb 验证了所有值:定时器有效并且寄存器 ICC_IGRPEN1_EL1
的最后一位设置为 1
。您是否注意到此代码中存在任何我未收到任何 IRQ 的错误?
不完全,我提到的其他功能实现如下:
void disable_cntv(void)
{
uint32_t cntv_ctl;
cntv_ctl = raw_read_cntv_ctl();
cntv_ctl &= ~CNTV_CTL_ENABLE;
__asm__ __volatile__("msr CNTV_CTL_EL0,%0\n\t" : : "r" (cntv_ctl) : "memory");
}
void enable_cntv(void)
{
uint32_t cntv_ctl;
cntv_ctl = raw_read_cntv_ctl();
cntv_ctl |= CNTV_CTL_ENABLE;
__asm__ __volatile__("msr CNTV_CTL_EL0,%0\n\t" : : "r" (cntv_ctl) : "memory");
}
uint32_t raw_read_cntfrq_el0(void)
{
uint32_t cntfrq_el0;
__asm__ __volatile__("mrs %0,CNTFRQ_EL0\n\t" : "=r" (cntfrq_el0) : : "memory");
return cntfrq_el0;
}
void raw_write_cntv_cval_el0(uint64_t cntv_cval_el0)
{
__asm__ __volatile__("msr CNTV_CVAL_EL0,%0\n\t" : : "r" (cntv_cval_el0) : "memory");
}
uint64_t raw_read_cntvct_el0(void)
{
uint64_t cntvct_el0;
__asm__ __volatile__("mrs %0,CNTVCT_EL0\n\t" : "=r" (cntvct_el0) : : "memory");
return cntvct_el0;
}
/* Wait For Interrupt */
#define wfi() asm volatile("wfi" : : : "memory")
CNTV_CTL_ENABLE
的定义如下:
#define CNTV_CTL_ENABLE (1 << 0) /* Enables the timer */
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)