|ARM Technical Support Knowledge Articles|
A Bus Fault is an Error signal returned to the processor from the bus interconnect or selected slave device in response to a requested bus transfer.
For normal operation, there are two likely outcomes of a Bus Fault:
- the error is fatal, therefore the system is reset or the current task is killed by the operating system
- the error is fixable, therefore the desired outcome is that the problem is corrected by the exception handler and the bus access is retried after the return from exception
When an exception occurs, the current execution context is automatically pushed onto the current stack and the exception vector is loaded to run the exception handler code. The stacked context includes various items: link register (lr), combined program status register (xPSR), scratch registers (r0-r3, r12) and program counter (pc), which allows the processor transparently to return to the interrupted code after the exception has been handled. It is therefore normal for the stacked pc to be the address of the faulting instruction, so that this instruction will be re-executed after the fault has been corrected.
If a test program causes a Bus Fault, but has no way of correcting the fault, it will continually return from the exception handler and re-execute the faulting instruction, causing the fault to be triggered repeatedly.
There are at least two ways to overcome this situation.
The return address (the pc in the stacked context) can be modified so that the return from the exception handler is to the instruction following the opcode which caused the fault. This method is complicated by two issues. The stacked context may be on one of two stacks if the Process Stack Pointer is in use, therefore it is necessary to inspect the current lr in the exception handler to determine which stack contains the relevant stack frame. It is then necessary to determine the size of the opcode which caused the fault, so that the correct adjustment to the stacked pc can be made. This requires the use of the stacked pc to locate the faulting opcode followed by analysis of the opcode to determine the opcode size (16- or 32-bit).
A simpler approach is to allow the faulting memory access to be repeated, but to modify the register which contains the base address for the access, such that the repeated memory access will now be to a non-faulting location. If the base register is one of the stacked scratch registers, it will still be necessary to determine which stack contains the stack frame in order to modify that register value, but if a non-scratch register is used for the base register, the register value can be modified directly in the handler to influence the memory access after the return-from-exception. This is the simplest solution.
Did you find this article helpful? Yes No
How can we improve this article?