|
From: | ckim |
Subject: | RE: interrupt occurs only once and not the second time.. (arm64 baremetal) |
Date: | Sat, 24 Apr 2021 23:35:16 +0900 |
Hi all, For information to others : The problem was that when I read the interrupt acknowledge register, I should have read ICC_IAR0_EL1 not ICC_IAR1_EL1 because I assigned the interrupt to group 0. Because the INTID I read from the ack register and the INTID I wrote to deactivate register was different, it was not deactivated. After fixing this, two interrupts are processed in sequence ok. Thanks. Chan Kim From: ckim@etri.re.kr <ckim@etri.re.kr> For anyone interested, Yesterday, when changed GICD_IGRPR register so that the interrupt is in secure group, the interrupt acknowledge was done ok (the value now correctly reads 0xD0 = 208). But the deactivation doesn’t work. (I tried using ICC_EIOR1_EL1 and ICC_EOIR0_EL1 to deactivate it but neither works) Anny suggestion is welcome. Thank you! Chan Kim From: ckim@etri.re.kr <ckim@etri.re.kr> 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> Dear list members, I’m 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 peripheral’s interrupt), after the eret, the interrupt status is still ‘active’ even though I deactivated it. (The peripheral interrupt’s INTID is 208. So It’s 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. I’ll 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 |
[Prev in Thread] | Current Thread | [Next in Thread] |