1/1

|
openrisc stack management
by jamesedgar on Sep 6, 2011 |
jamesedgar
Posts: 9 Joined: Sep 14, 2004 Last seen: Jun 26, 2020 |
||
|
I've got a version of telnet running on OpenRISC on a spartan 3 board. I have been seeing intermittent errors, and I discovered that the problem occurs when either the stack prologue or epilogue is interrupted. What occurs is (epilogue example) the stack pointer is changed in anticipation of recovering the return address, then the interrupt occurs and overwrites the return address.
Example: before interrupt network_device_read: EA =0000eadc PA =0000eadc r2 =00000000 00006bc4 l.sw -8(r1),r2 r2 =0000eae4 r1 =0000eae4 00006bc8 l.addi r2,r1,0x0 //return address put on stack EA =0000eae0 PA =0000eae0 r9 =0000aef4 00006bcc l.sw -4(r1),r9 //stack pointer moved to include added variables r1 =0000ead8 r1 =0000ead8 00006bd0 l.addi r1,r1,-12 r3 =00000000 00006bd4 l.movhi r3,0 r3 =0000e300 r3 =0000e300 00006bd8 l.ori r3,r3,0xe300 r3 =00000000 EA =0000e300 PA =0000e300 00006bdc l.lwz r3,0x0(r3) r3 =00000000 00006be0 l.sfeqi r3,0x0 SR =00008607 00006be4 l.bf 0x9 00006be8 l.nop 0 r3 =00000000 00006c08 l.addi r3,r0,0x0 r11=00000000 r3 =00000000 00006c0c l.ori r11,r3,0 //r1 moves back below return address in anticipation of reading return address r1 =0000eae4 r2 =0000eae4 00006c10 l.ori r1,r2,0 Now the interrupt occurs. The stack pointer has already been moved below the return addresss Finally, after the interrupt: r31=00000000 EA =0000eae0 PA =0000eae0 0000100c l.lwz r31,0x70(r1) r1 =0000eae4 r1 =0000eae4 00001010 l.addi r1,r1,0x74 00001014 l.rfe //we're back, but now we need to recover return address from stack r2 =00000000 EA =0000eadc PA =0000eadc 00006c14 l.lwz r2,-8(r1) // return address is wrong since it was overwritten during the interrupt r9 =00000000 EA =0000eae0 PA =0000eae0 00006c18 l.lwz r9,-4(r1) r9 =00000000 00006c1c l.jr r9 00006c20 l.nop 0 00000000 l.j 0x0 The network device read function is only called from the main function. The code above was generated using gcc version 4.5.1-or32-1.0rc1 (OpenRISC 32-bit toolchain for or32-elf (built 20110213)) I know there is an option to use context switching which could solve the problem, but it is not clear how it would be possible to safely use interrupts without atomic pop and push instructions if context switching is not used. Any suggestions? Thanks, Jamie |
|||
|
RE: openrisc stack management
by julius on Sep 6, 2011 |
julius
Posts: 363 Joined: Jul 1, 2008 Last seen: May 17, 2021 |
||
|
What exception handler code are you using?
It should step over the area known as the red zone, which is a certain amount of area underneath the stack pointer (up to 256 bytes I think) that can be used. If this area is avoided by the exception handler then all should be OK. At least, I think this is the problem. A quick test would be to compile all of your C code with the -mno-red-zone option. |
|||
|
RE: openrisc stack management
by jamesedgar on Sep 7, 2011 |
jamesedgar
Posts: 9 Joined: Sep 14, 2004 Last seen: Jun 26, 2020 |
||
|
Julius --
That was the solution. I had an older version of except.S that did not include any red zone space. Thanks for the info. Jamie |
|||
1/1

