Electrical – Undefined exception in ARM processor

armcortex

Undefined exception in ARM processors is described as being taken when the processor encounters an instruction that is undefined or not supported by implementation.

I am not able to understand that processor is in this mode is either due to program portability or due to the wrong instruction of some program which is not part of instruction sets of processor?

Best Answer

The processor enters "undefined mode" when it encounters an invalid instruction.

Not all possible bit patterns are valid instructions, and contrary to older processors where at least something happens, the processor detects these patterns and then generates an exception.

The handler for this exception is executed normally, but the processor mode is changed so that the R13_und and R14_und registers are mapped to R13 and R14. This is necessary because the handler requires a local stack and information about the faulting address.

The stack for the handler needs to be separate because it is not guaranteed that the code currently running has a valid stack. Simply using whatever R13 contained at this point would be a security issue, as the handler executes with supervisor privilege. Thus, the operating system at start reserves stack space for the Undefined handler and places the stack top address in R13_und (by switching to UND mode briefly):

    mrs r0, cpsr
    bic r1, r0, #0x1f
    orr r1, r1, #MODE_UND
    msr cpsr_c, r1
    ldr r13, =_und_stack_top
    msr cpsr_c, r0

The R14 register is also shadowed, because it is overwritten at exception entry, but the handler may decide to emulate the offending instruction and return to regular program flow, which would require restoring R14 (for which a stack would be required, which again is not guaranteed).

For example,

    bl  do_something
    ...

do_something:
    vstm r13!, {s3}
    ...
    vldm r13!, {s3}

The do_something function stores s3 on the stack, because it modifies it and wishes to restore it at the end, but doesn't save r14, because it doesn't call any subroutines. If the CPU doesn't have an FPU, the Undefined handler gets called for the vstm instruction.

Actual exception vector:

undefined:
    b undefined_handler

Handler:

undefined_handler:
    stm r13!, {r0-r4,r14}  // this goes on the UND handler stack
    ldr r0, -8[r14]        // look at the offending instruction
    ...                    // emulate instruction
    ldm r13!, {r0-r4,r14}  // restore everything from stack
    subs r15, r14, #8      // return from exception

The r14 value for do_something was hidden in the r14_USR register, which is not accessible from Undefined mode -- if the handler were interested in that, it would change to System mode (which is a privileged mode with access to USR registers), copy the value to another register and switch back to UND mode in order to get access to its own stack back.