URL: <http://savannah.nongnu.org/bugs/?45941>
Summary: [PATCH] Bug in interrupt handling with instructions that clear interrupt flag Project: Simulavr: an AVR simulator Submitted by: mhx Submitted on: Sat 12 Sep 2015 12:48:42 PM GMT Category: Simulation Severity: 3 - Normal Item Group: None Status: None Privacy: Public Assigned to: None Originator Email: simul...@mhxnet.de Open/Closed: Open Discussion Lock: Any Component Version: simulavrxx _______________________________________________________ Details: Hi! I believe I've found a bug in the way simulavr handles interrupts in the presence of instructions that disable global interrupts. In a nutshell, when an interrupt is detected and queued to be executed after the next statement and the next statement is either CLI or any other instruction that clears the global interrupt flag (OUT SREG, ...), the interrupt handler will still be called /after/ global interrupts have been disabled. This basically means that code that was meant to be uninterruptible (protected by CLI / SEI) can now be interrupted as the RETI will jump back to the first instruction after CLI and will even leave interrupts enabled. The documentation for CLI clearly states: "The interrupts will be immediately disabled. No interrupt will be executed after the CLI instruction, even if it occurs simultaneously with the CLI instruction." It isn't quite as clear for when OUT SREG clears the interrupt flag, but I verified that the behaviour is the same with an actual ATmega32u4. I noticed this behaviour when the scheduler for an RTOS I had written years ago was running amok if left running for long enough under simulavr. The code had been running for years without any issues, but failed on simulavr after ~6 seconds of simulation time. I've attached some example code to reproduce the problem. From the trace, you can see that __vector_6 is called after the execution of CLI (removed wait states for readability): clibug.elf 0x009c: main+0xd SEI SREG=[I-----Z-] clibug.elf 0x009e: main+0xe clibug.elf interrupt on index 6cleared IRQ prepared for addr c CLI SREG=[------Z-] clibug.elf 0x00a0: main+0xf IRQ DETECTED: VectorAddr: 12clibug.elf IrqSystem: IrqHandlerStarted Vec: 6 SP=0x45c 0x50 SP=0x45b 0x0 clibug.elf 0x0018: ,__vector_default+0xc JMP 6c __vector_6 clibug.elf 0x006c: __vector_6 PUSH R1 SP=0x45a 0x0 clibug.elf 0x006e: __vector_6+0x1 PUSH R0 SP=0x459 0xaa clibug.elf 0x0070: __vector_6+0x2 IN R0, 0x3f clibug.elf 0x0072: __vector_6+0x3 PUSH R0 SP=0x458 0x2 clibug.elf 0x0074: __vector_6+0x4 EOR R1, R1 SREG=[------Z-] clibug.elf 0x0076: __vector_6+0x5 NOP clibug.elf 0x0078: __vector_6+0x6 POP R0 SP=0x459 0x2 clibug.elf 0x007a: __vector_6+0x7 OUT 0x3f, R0 clibug.elf 0x007c: __vector_6+0x8 POP R0 SP=0x45a 0xaa clibug.elf 0x007e: __vector_6+0x9 POP R1 SP=0x45b 0x0 clibug.elf 0x0080: __vector_6+0xa RETI SP=0x45c 0x0 SP=0x45d 0x50 clibug.elf IrqSystem: IrqHandler Finished Vec: 6 clibug.elf 0x00a0: main+0xf NOP I've also attached a patch that aims to fix the problem by checking the current instruction before preparing interrupts. If the instructions will clear the interrupt flag, interrupt preparation will be skipped. I'm not sure this is the most elegant way to solve the problem, in particular as there is now some redundancy with the instruction decoder, but I couldn't think of a better way while at the same time keeping the code simple. I'm totally open for suggestions on how to do things differently :-) Thanks, Marcus PS: The example code was written for atmega16 and I've used the following commands to test it: # avr-gcc -mmcu=atmega16 -gstabs -O2 -std=gnu99 -DF_OSC=1000000 clibug.c -o clibug.elf # simulavr -d atmega16 -t clibug.trace -F 1000000 -m 10000000 -f clibug.elf _______________________________________________________ File Attachments: ------------------------------------------------------- Date: Sat 12 Sep 2015 12:48:42 PM GMT Name: clibug.c Size: 380B By: mhx <http://savannah.nongnu.org/bugs/download.php?file_id=34862> ------------------------------------------------------- Date: Sat 12 Sep 2015 12:48:42 PM GMT Name: fix-cli.patch Size: 3kB By: mhx <http://savannah.nongnu.org/bugs/download.php?file_id=34863> _______________________________________________________ Reply to this item at: <http://savannah.nongnu.org/bugs/?45941> _______________________________________________ Message sent via/by Savannah http://savannah.nongnu.org/ _______________________________________________ Simulavr-devel mailing list Simulavr-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/simulavr-devel