The Icon Bar: Programming: Data Abort handling
|
Data Abort handling |
|
sirbod (20:51 14/10/2012) sirbod (18:46 15/10/2012) TomWalker (20:46 15/10/2012) sirbod (07:50 16/10/2012) sirbod (08:05 16/10/2012) TomWalker (19:06 16/10/2012) sirbod (20:43 16/10/2012)
|
|
Jon Abbott |
Message #121230, posted by sirbod at 20:51, 14/10/2012 |
Member
Posts: 563
|
I've written a data abort handler, which works (tested on an ARM610/710), except when the data abort occurs in SVC.
Once I've established the abort is for my code and not the OS, I switch to the aborting CPU mode to save the registers. In SVC however, R14 is always corrupt - why?
The code is:
STR R0, DA_registers SUB R14, R14, #8 ; correct return address STR R14, DA_registers + 15*4
MRC P15, 0, R0, C6, C0 ;read fault address register
CMP R0, #&4E00000 CMPLO R0, #&1E00000 BLO _pass_to_OS_handler CMP R0, #&2000000 CMPHI R0, #&5000000 BHS _pass_to_OS_handler
STR R0, DA_address
MRS R0, SPSR_all ;get aborting CPU mode STR R0, DA_CPSR TST R0, #%1111 ;is it USR? BEQ _USR_mode ;YES
MSR CPSR_all, R0 ;NO, switch to aborting CPU state NOP MRS R0, SPSR_all ;store the aborting SPSR B _got_SPSR
._USR_mode MSR CPSR_all, R0 ;YES, switch to aborting CPU state NOP MOV R0, #0 ;no SPSR for USR mode
._got_SPSR STR R0, DA_SPSR ;store the aborting SPSR ADR R0, DA_registers + 4 STMIA R0, {R1-R14} ;store the aborting state registers
I've previously claimed the Data Abort vector via OS_ClaimProcessorVector.
How can I retrieve R14? More to the point, why is it corrupt?
EDIT: Added FAR entry code
EDIT2: Found the problem, extASM 2.0 has a fairly fatal bug where it doesn't encode "MSR CPSR_all, Rx" correctly - it ends up as "CMNP R3, R0". Also discovered another bug where NOP is encoded as "TEQP R0, #0"
EDIT3: The fixes for extASM are as follows:
To fix MSR CPSR, Rx / MSR SPSR, Rx assembler.arm.decode_psr_register/.Decode_PSR_Register - needs “MOVNE R0, #%1001” adding after “CMP R8, #’_’ “, so it defaults to “_all” if there’s no “_” present. NOTE this encoding is not SA compatible and is for 610/7X0 only.
To fix NOP assembler.arm.decode_misc_instruction/.DT_NOP - "MOV R9, #%....” needs replacing with “MOV R9, #&01A00000”
[Edited by sirbod at 20:18, 15/10/2012] |
|
[ Log in to reply ] |
|
Jon Abbott |
Message #121235, posted by sirbod at 18:46, 15/10/2012, in reply to message #121230 |
Member
Posts: 563
|
The next thing I need confirming, as the ARM datasheets are contradictory and I don't have an ARM9+ to check.
When a data abort occurs, are the following assumptions correct:
610 / 710 / 7500 (when in Late Abort Mode)
LDMxx/STMxx Rx! - Rx is updated, roll back before retrying the instruction
LDR/STR Rn, [Rx, xx]! - Rx is updated, roll back before retrying the instruction (NB this behaviour isn't implemented in Red Squirrelwhen emulating a 710 incidentally)
SA / ARM9 / ARM11 / Cortex
LDMxx/STMxx Rx! - Rx is rolled back by the CPU
LDR/STR Rn, [Rx, xx]! - Rx is rolled back by the CPU
NOTE: I'm only concerned with CPU's capable of running RO3.5+
[Edited by sirbod at 08:52, 16/10/2012] |
|
[ Log in to reply ] |
|
Tom Walker |
Message #121238, posted by TomWalker at 20:46, 15/10/2012, in reply to message #121235 |
Member
Posts: 25
|
SA uses the Base Restored Abort Model.
The ARM ARM suggests that the Red Squirrel behaviour is correct for ARMv3 and previous (the Early Abort Model). |
|
[ Log in to reply ] |
|
Jon Abbott |
Message #121242, posted by sirbod at 07:50, 16/10/2012, in reply to message #121238 |
Member
Posts: 563
|
SA uses the Base Restored Abort Model.
The ARM ARM suggests that the Red Squirrel behaviour is correct for ARMv3 and previous (the Early Abort Model). Cheers, I've updated the table above.
Red Squirel's implementation of the 710 needs a tweak to the LDR/STR handing during an abort, it seems to be fixed in Early Abort Mode.
I've yet to test any other emulators, although will need to. I wouldn't be surprised if a few others aren't quite right either, as the ARM documentation is so erratic on the Data Abort subject. Take for example the following statement from the Developer Guide, which is easy to misinterpret as all ARM7's being forced into Late Abort Mode for LDR/STR:
Single Register Load or Store (LDR or STR) The response depends on the processor type: • If the abort takes place on an ARM6-based processor: — If the processor is in early abort mode and writeback was requested, the address register will not have been updated. — If the processor is in late abort mode and writeback was requested, the address register will have been updated. The change must be undone. • If the abort takes place on an ARM7-based processor, including the ARM7TDMI, the address register will have been updated and the change must be undone. • If the abort takes place on an ARM9TM, ARM10TM, or StrongARM-based processor, the address is restored by the processor to the value it had before the instruction started. No further action is required to undo the change.
Swap (SWP) There is no address register update involved with this instruction.
Load Multiple or Store Multiple (LDM or STM) The response depends on the processor type: • If the abort takes place on an ARM6-based processor or ARM7-based processor, and writeback is enabled, the base register will have been updated as if the whole transfer had taken place. In the case of an LDM with the base register in the register list, the processor replaces the overwritten value with the modified base value so that recovery is possible. The original base address can then be recalculated using the number of registers involved. • If the abort takes place on an ARM9, ARM10, or StrongARM-based processor and writeback is enabled, the base register will be restored to the value it had before the instruction started. |
|
[ Log in to reply ] |
|
Jon Abbott |
Message #121243, posted by sirbod at 08:05, 16/10/2012, in reply to message #121242 |
Member
Posts: 563
|
Red Squirel's implementation of the 710 needs a tweak to the LDR/STR handing during an abort, it seems to be fixed in Early Abort Mode. I'll work around this by generating an abort for both LDR and LDM with writeback and see if the registers are updated. So more of an observation than an issue.
[Edited by sirbod at 09:05, 16/10/2012] |
|
[ Log in to reply ] |
|
Tom Walker |
Message #121246, posted by TomWalker at 19:06, 16/10/2012, in reply to message #121242 |
Member
Posts: 25
|
Red Squirel's implementation of the 710 needs a tweak to the LDR/STR handing during an abort, it seems to be fixed in Early Abort Mode. I believe this is correct, Early Abort Mode was abandoned (according to my copy of the ARM ARM) in ARMv3M and the 710 is plain ARMv3. |
|
[ Log in to reply ] |
|
Jon Abbott |
Message #121247, posted by sirbod at 20:43, 16/10/2012, in reply to message #121246 |
Member
Posts: 563
|
I believe this is correct, Early Abort Mode was abandoned (according to my copy of the ARM ARM) in ARMv3M and the 710 is plain ARMv3. RS doesn't match what I'm seeing on a physical ARM710, so something is odd. I've worked around it by checking each instruction group and tracking which is late/early.
RS - LDR is Early and LDM is Late ARM710 - LDR and LDM are Late
[Edited by sirbod at 21:44, 16/10/2012] |
|
[ Log in to reply ] |
|
|
The Icon Bar: Programming: Data Abort handling |