arm - 在 arm64 GICv3 中捕获 IRQ 的步骤?
问题描述
我正在开发一个裸机中断控制器,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 指南,中断组 1 启用寄存器,0
寄存器ICC_IGRPEN1_EL1
的位负责 IRQ 的激活。这是它的摘录:
我指定我在非安全模式下工作。
我想从时序上下文中生成一个 IRQ。计时器运行良好,但由于任何原因,即使位设置为 1 0
,也不会捕获 IRQ。ICC_IGRPEN1_EL1
由于我使用了多个标题,因此我无法为您提供最小示例。我没有办法,如果你能建议我怎么做,请做。但是,我已尽力提出一个明确的问题,所以我真的希望您能提供帮助。
这是生成 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 */
解决方案
推荐阅读
- kotlin - 为什么我们不能在 kotlin 中的属性 getter 字段周围添加块
- python - 如何用另一个数据框中的索引替换一个数据框中的空白索引
- javascript - MongoDB:如何更新对象数组中的特定对象?
- android - 将日期转换为 firetstore 时间戳
- r - 如何在可以设置顺序的一系列数据框的特定列上迭代函数?
- glsl - 有符号距离函数 - 3D 平面
- java - 在根项目中找不到 Gradle 项目
- sql - SQL:执行窗口函数并找到百分比
- html - 使用 :target, html5 更改其他元素的样式
- python - 什么是 PyQt 等价于 WinForms 激活事件?