qemu-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: interrupt occurs only once and not the second time.. (arm64 baremeta


From: ckim
Subject: RE: interrupt occurs only once and not the second time.. (arm64 baremetal)
Date: Fri, 23 Apr 2021 19:31:38 +0900

Hello all,

Regarding my case below, I found the first interrupt is taken as spurious (when I read the interrupt acknowledge register, ICC_IAR0_EL1, ICC_IAR1_EL1, they both read 1023).

And set enable, clear enable registers seems to be correct. (without it , interrupt never occurs). Exception syndrome is zero (because this is async interrupt). I’ve set the interrupt as edge trigger.

And the corresponding target register (GICD_ITARGETSR) doesn’t have any effect. (this is a single CPU case). No matter what value I set to those target registers, the first interrupt happens (exception occurs, fiq handled and eret executed to the main routine). It is set to nonsecure group1.

Any suggestion will be appreciated.

Thanks!

Chan Kim

 

From: ckim@etri.re.kr <ckim@etri.re.kr>
Sent: Thursday, April 22, 2021 9:02 PM
To: 'qemu-discuss' <qemu-discuss@nongnu.org>
Subject: interrupt occurs only once and not the second time.. (arm64 baremetal)

 

Dear list members,

 

Im running a simple baremetal program on a virtual machine copied from hw/arm/virt.c but my machine contains a simple peripheral device.

The peripheral device generates interrupt using qemu_set_irq(s->irq, 1) when a register is written, and clears the interrupt using qemu_set_irq(s->irq, 0) when the interrupt flag is read.

My problem is, after the exception handling (which contains the handler for that peripherals interrupt), after the eret, the interrupt status is still active even though I deactivated it.

(The peripheral interrupts INTID is 208. So Its SPI 176). And right after the eret, in the main thread, the interrupt enable bits are read all zero. But after a print, it is read as all 1 (enabled).

That is very strange.

 

Below is the deactivate function my colleage wrote. Ill read/investigate further about the interrupt settings (group, leve/edge, etc) but can anyone find anything suspicious below?

Or I would appreciate any suggestion on where to check.

 

static inline void set_interrupt_deactive(uint64_t intid)

{

  uint64_t eoimode;

  asm volatile ("mrs %[eoimode], s3_0_c12_c12_4" : [eoimode] "=r" (eoimode) :);

  if (!((eoimode & 0x2) == 0x2))

  {

    // if eiomode == 0, priority drop is interrupt deactive.

    asm volatile ("msr s3_0_c12_c12_1, %[intid]" : : [intid] "r" (intid)); // Drop INTID

  }

  else

  {

    asm volatile ("msr s3_0_c12_c12_1, %[intid]" : : [intid] "r" (intid)); // Drop INTID

   asm volatile ("msr s3_0_c12_c11_1, %[intid]" : : [intid] "r" (intid)); // Deactive INTID

  }

}

You can see the register names.

#define ICC_CTLR_EL1        S3_0_C12_C12_4

#define ICC_EOIR1_EL1       S3_0_c12_c12_1

#define ICC_DIR_EL1     S3_0_C12_C11_1 

 

Thank you very much.

Regards,

Chan Kim


reply via email to

[Prev in Thread] Current Thread [Next in Thread]