mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-29 20:34:36 +00:00 
			
		
		
		
	 04b95f3567
			
		
	
	04b95f3567
	
	
	
		
			
			Commit 891eb3b0 was fixing an issue with PS and EPC1 not being
preserved after the window spill procedure. It did so by saving PS in
a2 and EPC1 in a4. However the a4 register may be a live register of
another window in the call stack, and if it is overwritten and then
spilled to the stack, then the corresponding register value will end
up being corrupted. In practice the problem would show up as an
IllegalInstruction exception, when trying to return from a function
when a0 value was 0x40020.
Fix by using a0 register instead of a4 as scratch. Also fix a comment
about xthal_save_extra_nw, as this function in fact doesn't clobber
a4 or a5 because XCHAL_NCP_NUM_ATMPS is defined as 1.
Closes https://github.com/espressif/esp-idf/issues/5758
		
	
		
			
				
	
	
		
			56 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			56 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /* Helper function for the test case in test_context_save_clobber.c */
 | |
| 
 | |
| #if defined(__XTENSA__)
 | |
| #include "xtensa/config/core-isa.h"
 | |
| #if defined(XCHAL_HAVE_WINDOWED)
 | |
| 
 | |
|     .data
 | |
| recursion_count:
 | |
|     .word 0
 | |
| 
 | |
|     .text
 | |
|     .global     test_context_save_clober_func
 | |
|     .type       test_context_save_clober_func,@function
 | |
|     .align      4
 | |
| 
 | |
| /* This function recursively calls itself via call4, making sure each frame
 | |
|  * uses only 4 registers. For this reason, recursion count can not be
 | |
|  * a function argument (it would have to be in a6) and is placed into .data
 | |
|  * section above.
 | |
|  */
 | |
| test_context_save_clober_func:
 | |
|     entry a1, 16
 | |
| 
 | |
|     /* load recursion count from memory */
 | |
|     movi a3, recursion_count
 | |
|     l32i a2, a3, 0
 | |
| 
 | |
|     /* if it is zero, initialize it to 16 (=64 physical registers / 4 registers per call) */
 | |
|     bnez a2, 1f
 | |
|     movi a2, 16
 | |
| 1:
 | |
| 
 | |
|     /* decrement the counter and write it back */
 | |
|     addi a2, a2, -1
 | |
|     s32i a2, a3, 0
 | |
| 
 | |
|     /* counter not zero? do a recursive call */
 | |
|     beqz a2, wait
 | |
|     call4 test_context_save_clober_func
 | |
|     j end
 | |
| 
 | |
| wait:
 | |
|     /* Counter has reached zero, and we have 16 frames on the stack.
 | |
|      * Delay for a few seconds, expecting in interrupt to happen.
 | |
|      */
 | |
|     movi a3, 100000000
 | |
| 1:
 | |
|     addi a3, a3, -1
 | |
|     bnez a3, 1b
 | |
| 
 | |
| end:
 | |
|     retw
 | |
| 
 | |
| #endif // XCHAL_HAVE_WINDOWED
 | |
| #endif // __XTENSA__
 |