Как заставить таймер IRQ работать на QEMU (-machine virt -cpu cortex-a57) - PullRequest
0 голосов
/ 29 июня 2018

Я пытаюсь прерывать таймер на QEMU (-machine virt -cpu cortex-a57), но все еще не работает до сих пор. У меня есть несколько вопросов, и мне нужно ваше предложение. Я очень ценю вашу помощь.

[Исправлено] Проблема исправлена ​​в armv8-bare-metal (коммит 7aaa433576602b93d426f63b1a8a9fe473a52506). Я могу получить правильный исключение (с GDB) на основе таймера IRQ. Основная причина - отсутствие настройки GIC.

  1. Есть ли простой пример для меня ссылки? Или где мне задать вопрос?

  2. Кто-то может дать мне несколько советов в моем текущем исследовании armv8-bare-metal (commit b72c6a8cc7033a4fed89b57f75826d201466179f)? Текущее состояние таково, что мы можем видеть изменения CNTV_CTL_EL0: bit2 (ISTATUS), но функция обратного вызова дескриптора irq_interrupt не вызывается, и мы также не наблюдаем никаких изменений в ISR_EL1 (нет ожидающих прерываний IRQ).

2-1. Я обновляю процедуру, добавляю конфигурацию gic. Но все равно не работает. Нужна помощь. 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
...