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

Timer 如何使计时器irq在QEMU上工作(-machine virt-cpu cortex-a57),timer,qemu,arm64,bare-metal,Timer,Qemu,Arm64,Bare Metal,我正在QEMU(-machine virt-cpu cortex-a57)上尝试定时器中断,但直到现在仍然失败。我有几个问题需要你的建议,非常感谢你的帮助 [已修复]问题已在(提交)中修复 7aaa433576602b93d426f63b1a8a9fe473a52506)。我能得到正确的答案 基于异常(使用GDB)的计时器IRQ。根本原因是缺少GIC设置 有没有简单的例子供我参考?或者我应该在哪里问这个问题 在我目前的研究中,有人可以给我一些建议(提交b72c6a8cc7033a4fed89b5

我正在QEMU(-machine virt-cpu cortex-a57)上尝试定时器中断,但直到现在仍然失败。我有几个问题需要你的建议,非常感谢你的帮助

[已修复]问题已在(提交)中修复 7aaa433576602b93d426f63b1a8a9fe473a52506)。我能得到正确的答案 基于异常(使用GDB)的计时器IRQ。根本原因是缺少GIC设置

  • 有没有简单的例子供我参考?或者我应该在哪里问这个问题

  • 在我目前的研究中,有人可以给我一些建议(提交b72c6a8cc7033a4fed89b57f75826d201466179f)? 目前的状态是,我们可以看到CNTV_CTL_EL0:bit2(ISTATUS)发生变化,但没有调用irq_中断句柄回调函数,我们也没有观察到ISR_EL1中的任何变化(没有检测到irq中断挂起)

  • 2-1。我更新程序,添加gic配置。但还是不行。我需要帮助。(提交80CDCD3AEC0942B5AF28ACAF350C136ABF1A730)

    程序/日志如下所示

    $ 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
    

    1.以下是来自ARM Trusted固件的[1],它使用定时器相关寄存器生成时间IRQ并处理它。2.与每个步骤共享您的输出,以显示计时器是如何失败的。[1] :谢谢你的建议。我试试看。谢谢大家。问题已经解决,我可以根据计时器IRQ获得正确的异常。