如何使计时器irq在QEMU上工作(-machine virt -cpu cortex-a57)

时间:2018-06-29 04:04:15

标签: timer qemu arm64 bare-metal

我正在尝试在QEMU(-machine virt -cpu cortex-a57)上执行计时器中断,但是到目前为止仍然失败。我有几个问题,需要您的建议,非常感谢您的帮助。

  

[已修复] armv8-bare-metal中的问题已解决(提交   7aaa433576602b93d426f63b1a8a9fe473a52506)。我可以得到正确的   异常(使用GDB)基于计时器IRQ。根本原因是缺少GIC设置。

  1. 有没有简单的示例可供我参考?还是我应该在哪里问这个问题?

  2. 有人可以在我的当前研究armv8-bare-metal中给我一些建议(提交b72c6a8cc7033a4fed89b57f75826d201466179f)吗? 当前状态是我们可以看到CNTV_CTL_EL0:bit2(ISTATUS)发生了变化,但是没有调用irq_interrupt句柄回调函数,并且我们也没有观察到ISR_EL1发生任何变化(没有检测到IRQ中断待处理)。

2-1。我更新程序,添加配置。但是仍然不起作用。需要帮忙。 armv8-bare-metal(提交80cdcd3aec00942b5af28acaf350c136abf1a730)?

过程/日志如下。

$ make run
qemu-system-aarch64 -machine virt -cpu cortex-a57 -nographic -kernel kernel.elf

/* init_gicd( ) */
REG_GIC_GICD_CTLR: 0x00000000 08000000 = 0x00000000 00000000
Write REG_GIC_GICD_ICENABLER:
0x00000000 08000180 = 0x00000000 FFFFFFFF
0x00000000 08000184 = 0x00000000 FFFFFFFF
Write REG_GIC_GICD_ICPENDR:
0x00000000 08000280 = 0x00000000 FFFFFFFF
0x00000000 08000284 = 0x00000000 FFFFFFFF
REG_GIC_GICD_IPRIORITYR:
0x00000000 08000400 = 0x00000000 FFFFFFFF
0x00000000 08000404 = 0x00000000 FFFFFFFF
0x00000000 08000408 = 0x00000000 FFFFFFFF
0x00000000 0800040C = 0x00000000 FFFFFFFF
0x00000000 08000410 = 0x00000000 FFFFFFFF
0x00000000 08000414 = 0x00000000 FFFFFFFF
0x00000000 08000418 = 0x00000000 FFFFFFFF
0x00000000 0800041C = 0x00000000 FFFFFFFF
0x00000000 08000420 = 0x00000000 FFFFFFFF
0x00000000 08000424 = 0x00000000 FFFFFFFF
0x00000000 08000428 = 0x00000000 FFFFFFFF
0x00000000 0800042C = 0x00000000 FFFFFFFF
0x00000000 08000430 = 0x00000000 FFFFFFFF
0x00000000 08000434 = 0x00000000 FFFFFFFF
0x00000000 08000438 = 0x00000000 FFFFFFFF
0x00000000 0800043C = 0x00000000 FFFFFFFF
REG_GIC_GICD_ITARGETSR:
0x00000000 08000820 = 0x00000000 00000000
0x00000000 08000824 = 0x00000000 00000000
0x00000000 08000828 = 0x00000000 00000000
0x00000000 0800082C = 0x00000000 00000000
0x00000000 08000830 = 0x00000000 00000000
0x00000000 08000834 = 0x00000000 00000000
0x00000000 08000838 = 0x00000000 00000000
0x00000000 0800083C = 0x00000000 00000000
REG_GIC_GICD_ICFGR:
0x00000000 08000C04 = 0x00000000 00000000
0x00000000 08000C08 = 0x00000000 00000000
0x00000000 08000C0C = 0x00000000 00000000
REG_GIC_GICD_CTLR: 0x00000000 08000000 = 0x00000000 00000001

/* init_gicc( ) */
GICC_CTLR: 0x00000000 08010000 = 0x00000000 00000000
REG_GIC_GICC_PMR: 0x00000000 08010004 = 0x00000000 000000FF
REG_GIC_GICC_BPR : 0x00000000 08010008 = 0x00000000 00000000
REG_GIC_GICC_EOI : Clear all of the active interrupts
REG_GIC_GICC_CTLR : 0x00000000 08010000 = 0x00000000 00000001

/* gicd_enable_int(27) */
REG_GIC_GICD_ISENABLER: 0x00000000 08000100 = 0x00000000 0800FFFF

/* Virtual Timer config */
CurrentEL = 0x00000000 00000004    /* EL1 */
DAIF = 0x00000000 000003C0         /* DAIF bits are set */
CNTV_CTL_EL0 = 0x00000000 00000000
Disable the timer, CNTV_CTL_EL0 = 0x00000000 00000000 /* Clear bits of ENABLE/IMASK */
CNTFRQ_EL0 = 0x00000000 03B9ACA0   /* frequency of the system counter = 62.5MHz */ 
CNTVCT_EL0 = 0x00000000 000242C5   /* current 64-bit virtual count value */
Set it as next 1 sec, CNTV_CVAL_EL0 = 0x00000000 03BBEF65 /* set compare value */
Enable the timer, CNTV_CTL_EL0 = 0x00000000 00000001  /* Set bit ENABLE */
Enable IRQ, DAIF = 0x00000000 00000340  /* Clear IRQ mask bit */

/* we observe the CNTVCT_EL0 and CNTV_CTL_EL0 */
/* if time up, CNTV_CTL_EL0[2] = 1 */
CNTVCT_EL0 = 0x00000000 000390CA, CNTV_CTL_EL0 = 0x00000000 00000001
CNTVCT_EL0 = 0x00000000 0003D41F, CNTV_CTL_EL0 = 0x00000000 00000001
...
/* time up, CNTV_CTL_EL0[2]: ISTATUS = 1*/
CNTVCT_EL0 = 0x00000000 03BCE5C4, CNTV_CTL_EL0 = 0x00000000 00000005
SPSR_EL1 = 0x00000000 00000000
ISR_EL1 = 0x00000000 00000000
/* But the irq_handler doesn't be called and ISR_EL1[7] = 0 */
/* there is no IRQ interrupt pending detected */
QEMU: Terminated

0 个答案:

没有答案