log in | register | forums
Show:
Go:
Forums
Username:

Password:

User accounts
Register new account
Forgot password
Forum stats
List of members
Search the forums

Advanced search
Recent discussions
- Drag'N'Drop Autumn edition now available (News:)
- !DualHead puts 2 screens in one (News:)
- RISC OS London Show 2017 - Notes from the talks (News:6)
- November News (News:)
- !Organizer 2.28 reviewed (News:2)
- !OBrowse reviewed (News:10)
- Aemulor (Gen:16)
- DDE reaches release 28 and above (News:)
- Elesar quicks dispels stormy clouds (News:2)
- RISC OS London Show 2017 (News:)
Latest postings RSS Feeds
RSS 2.0 | 1.0 | 0.9
Atom 0.3
Misc RDF | CDF
Site Search
 
Article archives
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