johnprice
Posts: 2
Joined: Sat May 12, 2018 1:05 pm

Is there any way to emulate timer interrupt in qemu?

Sat May 12, 2018 1:21 pm

I've tested the system timer (whose base address is 0x3f003000) and the local timer (whose base is 0x3f00b000). They can work on my pi3, but it seems that none of them are emulated in qemu (I use qemu 2.12, which supports -M raspi3).

Can we emulate timer interrupts in qemu? Thanks.

User avatar
Ultibo
Posts: 135
Joined: Wed Sep 30, 2015 10:29 am
Location: Australia
Contact: Website

Re: Is there any way to emulate timer interrupt in qemu?

Tue May 15, 2018 12:12 am

johnprice wrote:
Sat May 12, 2018 1:21 pm
I've tested the system timer (whose base address is 0x3f003000) and the local timer (whose base is 0x3f00b000). They can work on my pi3, but it seems that none of them are emulated in qemu (I use qemu 2.12, which supports -M raspi3).

Can we emulate timer interrupts in qemu? Thanks.
Looking at the QEMU source it seems it still does not support he System Timer device in the Raspberry Pi emulation.

However the -M raspi2 and -M raspi3 emulations do include the ARM generic timer device (per processor core) and it does appear to have the interrupts connected so you should be able to use that one instead.

See the appropriate ARM Architecture Reference Manual for details of programming the generic timer.
Ultibo.org | Make something amazing
https://ultibo.org

Threads, multi-core, OpenGL, Camera, FAT, NTFS, TCP/IP, USB and more in 3MB with 2 second boot!

johnprice
Posts: 2
Joined: Sat May 12, 2018 1:05 pm

Re: Is there any way to emulate timer interrupt in qemu?

Tue May 15, 2018 2:46 am

Ultibo wrote:
Tue May 15, 2018 12:12 am
Looking at the QEMU source it seems it still does not support he System Timer device in the Raspberry Pi emulation.

However the -M raspi2 and -M raspi3 emulations do include the ARM generic timer device (per processor core) and it does appear to have the interrupts connected so you should be able to use that one instead.

See the appropriate ARM Architecture Reference Manual for details of programming the generic timer.
Thanks for the information. I have successfully triggered the generic timer interrupts in QEMU!

It's mainly documented in page 13 of QA7_rev3.4. Actually I tried the generic timer before but I forgot to enable CNTPNSIRQ. Now finally it works. :lol:

damon2
Posts: 5
Joined: Fri May 18, 2018 6:03 am

Re: Is there any way to emulate timer interrupt in qemu?

Fri May 18, 2018 6:20 am

Hello all,

I'm also trying to use the generic timer on raspberry pi 3 on qemu but I can't seem to trigger an interrupt.

I've initialized the registers:

(*40000040) |= (1 << 3) | (1 << 0);

(*40000060) |= (1 << 3) | (1 << 0);

and also initialized the timer value and the enabled the timer:

/* sets the timer value CNTP_TVAL_EL0 */
CntpTvalEl0Set(1000000 - 1);

/* sets CNTP_CTL_EL0 to enable the timer */
pharosCpuCntpCtlEl0Set(1 << 0);


when loop to find out the state, this is the output:

Current count = 1930792 , timer value = 210376 , compare = 2141180, control = 1
Current count = 1951566 , timer value = 189602 , compare = 2141180, control = 1
Current count = 1971509 , timer value = 169657 , compare = 2141180, control = 1
Current count = 1993148 , timer value = 148019 , compare = 2141180, control = 1
Current count = 2013817 , timer value = 127351 , compare = 2141180, control = 1
Current count = 2032500 , timer value = 108668 , compare = 2141180, control = 1
Current count = 2050739 , timer value = 90427 , compare = 2141180, control = 1
Current count = 2069562 , timer value = 71606 , compare = 2141180, control = 1
Current count = 2088245 , timer value = 52923 , compare = 2141180, control = 1
Current count = 2107750 , timer value = 33417 , compare = 2141180, control = 1
Current count = 2127648 , timer value = 13519 , compare = 2141180, control = 1
Current count = 2148749 , timer value = -7583 , compare = 2141180, control = 5
Current count = 2171610 , timer value = -30444 , compare = 2141180, control = 5
Current count = 2194009 , timer value = -52842 , compare = 2141180, control = 5

That is, the counter is always increasing, the timer value is decreasing down to zero and then to a negative number, the CVAL is always the same (I guess is automatically calculated) and the control (CNTP_CTL_EL0) changes the 3rd bit to one, indicating a pending interrupt. However, I don't seem to get the interrupt triggered at all.

There are some documents out there: https://www.raspberrypi.org/documentati ... rev3.4.pdf or https://web.stanford.edu/class/cs140e/d ... herals.pdf but I'm having difficulties understanding the interrupt controller mechanism. Should one use the 0x3F00b200 address to manage the interrupts or the 0x40000040? Or both?


Could you tell me what I missed?

Thank you!

LdB
Posts: 827
Joined: Wed Dec 07, 2016 2:29 pm

Re: Is there any way to emulate timer interrupt in qemu?

Sat May 19, 2018 5:09 pm

The sequence on a real PI3 is

1.) Route the local timer to a core register 0x40000024 (bits 0..2)
QA7_rev3.4.pdf page 18 ... say write 0 which is core 0

2.) Setup timer status control register 0x40000034 (all 32 bits)
QA7_rev3.4.pdf page 17 ... reload value 5000000 = like half sec, enable clock, enable interrupt
You can play with clock prescalers etc later.

3.) Hit timer interrupt clear and reload register 0x40000038 (bits 30 & 31)
QA7_rev3.4.pdf page 18 ... write 1 to both bits which clears irq signal and loads value from above

4.) Setup timer interrupt control register 0x40000040 (all bits ... zero all but the one bit set)
QA7_rev3.4.pdf page 13 ... now this depends what mode Core0 leaves your bootstub in.
If you did no EL changes in stub the core0 will still be in Hyp mode if like me you dropped it to SVC mode it is Non Secure

If Core0 enters in Hyp mode ... set nCNTHPIRQ_IRQ bit 1
If Core0 enters in Svc mode ... set nCNTPNSIRQ_IRQ bit 2

5.) Now you need to enable global interupts
asm(" cpsie i")


Now in the interrupt handler which you will have connected to the IRQ in vector table
You need to repeat step3 inside it to clear irq and reload timer

Code: Select all

void __attribute__((interrupt("IRQ")))  irq_handler_stub(void) {

     // Hit timer interrupt clear and reload register   0x40000038 (bits 30 & 31)
      // QA7_rev3.4.pdf page 18 ... write 1 to both bits which clears irq signal and loads value again
}
If it helps to look at C code
https://github.com/LdB-ECM/Raspberry-Pi ... ker/main.c
If you have a Pi3 and want to see what it does load the files on SD Card
https://github.com/LdB-ECM/Raspberry-Pi ... er/DiskImg

eggmansan
Posts: 2
Joined: Tue May 22, 2018 3:27 am

Re: Is there any way to emulate timer interrupt in qemu?

Tue May 22, 2018 3:37 am

Hi all.

I made simple generic timer sample programs.

for QEMU -m raspi3
https://github.com/eggman/raspberrypi/t ... i3/timer01

for QEMU -m raspi2
https://github.com/eggman/raspberrypi/t ... i2/timer01

result log
$ make
$ make run
CNTFRQ : 0x3B9ACA0
CNTV_TVAL: 0x3B91CDC
handler CNTV_TVAL: 0xFFFAB93A
handler CNTVCT : 0x3CFD0C4
handler CNTV_TVAL: 0xFFFDC8FD
handler CNTVCT : 0x78CFBA8
handler CNTV_TVAL: 0xFFFD62D6

damon2
Posts: 5
Joined: Fri May 18, 2018 6:03 am

Re: Is there any way to emulate timer interrupt in qemu?

Fri May 25, 2018 6:52 am

Hello all,

Thanks LdB! I just got my first interrupt running on qemu with raspberry pi 3, thanks to your example!

Also thanks to eggmansan, I did not check your example yet but I'll take a look soon.

Best regards

maldus
Posts: 22
Joined: Fri Dec 15, 2017 8:36 am

Re: Is there any way to emulate timer interrupt in qemu?

Tue Aug 21, 2018 2:57 pm

Sorry if I barge in. I'm trying to work with raspberry pi, interrupts and Qemu as well, and I couldn't help but notice that you are talking about RPi3 while quoting a reference for the Quad-A7 core (https://www.raspberrypi.org/documentati ... rev3.4.pdf).
Doesn't RPi3 have a Cortex A-53?

LdB
Posts: 827
Joined: Wed Dec 07, 2016 2:29 pm

Re: Is there any way to emulate timer interrupt in qemu?

Tue Aug 21, 2018 4:16 pm

It does but the multicore errata hardware area remains the same.

Working code example is here including pre-compiled img files in DiskImg directory
https://github.com/LdB-ECM/Raspberry-Pi ... 3Interrupt

Return to “Bare metal, Assembly language”

Who is online

Users browsing this forum: No registered users and 3 guests