Entry | |
---|---|
R0 | Reason code: |
0 = Register handler | |
1 = Deregister handler | |
R1 | Low address (inclusive) |
R2 | High address (exclusive) |
R3 | Address of handler routine |
R4 | R12 value for handler routine |
Exit | |
---|---|
- | All registers preserved |
The abort trapping system allows for data and prefetch aborts to be handled at a higher level than previously possible (e.g. via OS_ClaimProcessorVector or the environment handlers). They are designed to be easy to use for purposes such as implementing on-demand page mapping or virtual hardware devices; i.e. where the code can interact with the address range as if it were normal memory, with the OS and AbortTrap silently handling any aborts by emulating the aborting instruction and then resuming execution.
When a data abort occurs, the kernel will decode the instruction to determine the type of access (e.g. read or write), the address range being accessed, and which registers the data should be transferred in/out of. The kernel will then attempt to emulate the load/store operation, by invoking the relevant AbortTrap handler(s) for the region.
Handlers have three ways of responding to requests:
AbortTrap handlers are invoked after the OS_ClaimProcessorVector handlers, and before the data/prefetch abort environment handlers. This means that if there’s an abort which AbortTrap isn’t able to handle (e.g. there’s a part of the address range which isn’t covered by a handler, or where the handler has declined the request), then the kernel will restore the original registers and control will pass to the data/prefetch environment handler.
AbortTrap handlers will only be invoked for translation faults (no memory at the target address) or permission faults (e.g. attempting to write to read-only memory). Other types of fault (alignment faults, or hardware faults like cache parity errors) will not result in handlers being invoked, and there is no guarantee that unpredictable instructions (e.g. LDM which loads the base register but also applies writeback) will be processed. AbortTrap processing will not be performed if there is insufficient space in the SVC stack or the kernel believes the stack pointer is corrupt.
For aborts which cross page boundaries, it’s possible that only one of the pages is responsible for generating the abort, and the other page would have been able to service the request directly without aborting. The kernel will detect this and make sure that AbortTrap handlers are only invoked for pages where the abort was necessary; for pages where no abort would be generated, the kernel will emulate the access itself by directly copying to/from the relevant address range.
When the kernel invokes an AbortTrap handler, it can ask it to do one of two things:
Entry | |
---|---|
R0 | Bits 0-3: Reason code: |
0 = Store operation. Bit 4 indicates if the access is privileged (1) or unprivileged (0). | |
1 = Load operation. Bit 4 indicates if the access is privileged (1) or unprivileged (0). | |
2 = Memory map operation. Bits 4-9 indicate the required permissions. | |
3+ Reserved | |
Bits 4+: Flags | |
R1 | Pointer to buffer to use as data source (reason 0) or destination (reason 1). Invalid for memmap requests (reason 2). |
R2 | Base address of memory being accessed |
R3 | Length of memory being accessed (bytes) |
R12 | R4 value specified when routine was registered |
- | Entered in SVC mode with interrupts disabled |
Exit | |
---|---|
- | On success, V clear and the buffer contents updated (if applicable) |
On failure, V set and R0 pointing to an appropriate error block | |
All other registers preserved |
Care must be taken to ensure that an error is returned if the handler is called with unsupported/unrecognised reason code or flags.
For memmap operations, the permission flags are:
Bit | Meaning |
---|---|
4 | Executable in user mode |
5 | Writeable in user mode |
6 | Readable in user mode |
7 | Executable in privileged modes |
8 | Writeable in privileged modes |
9 | Readable in privileged modes |
This is the same pattern as used by OS_Memory 18.
Where possible, it’s preferable to use Abortable Dynamic Areas instead of directly registering with OS_AbortTrap.
Code which registers AbortTrap handlers may also need to respond to Service_ValidateAddress, in order for the OS & software to consider the address range as valid.
Regions which handlers are asked to service have no size or alignment guarantees, other than the minimum size being one byte, and the requested region being fully within the low/high addresses specified when the handler was registered.
For handler reasons 0 & 1, bytes should be transferred in linear order; the kernel will take care of any rotation required by pre-ARMv7 rotated loads.
SWP/SWPB instructions are emulated as a load operation (handler reason 1) followed by a store operation (handler reason 0). If the handler maps in the page as part of the read operation, the kernel may directly emulate the store by copying the data itself.
Currently, data aborts from Thumb mode are not handled and will be passed straight on to the abort environment handler.
StrongARM abort handling errata are not dealt with, so care must be taken when using handlers on afflicted CPUs (see Notable CPU bugs).
For operations which cross multiple regions (e.g. multiple AbortTrap regions or directly-accessible memory regions), and where the overall result is a failure:
This behaviour is broadly consistent with the ARM abort model.
This call is available in RISC OS Select and RISC OS 5.29+. Differences between RISC OS 5 and RISC OS Select are: