5.3.4. Multi-ICE

To ensure that the application SWI handler will successfully cooperate with Multi-ICE semihosting mechanism:

  1. Install the application SWI handler into the vector table.

  2. Modify $semihosting_vector to point to a location at the end of the application handler. This point in the handler must only be reached if your handler does not handle the SWI.

Before Multi-ICE traps the SWI, your SWI handler must restore all registers to the values they had when your SWI handler was entered. Typically, this means that your SWI handler must store the registers to a stack on entry and restore them before falling through to the semihosting vector address.


It is essential that the actual position $semihosting_vector points to within the application handler is correct.

See exception handling in the ADS Developer Guide for writing SWI handlers.

The following example SWI handler can detect if it fails to handle a SWI. In this case, it branches to an error handler:

; r0 = 1 if SWI handled
    CMP r0, #1                ; Test if SWI has been handled.
    BNE NoSuchSWI             ; Call unknown SWI handler.
    LDMFD sp!, {r0}           ; Unstack SPSR...
    MSR spsr_cxsf, r0         ; ...and restore it.
    LDMFD sp!, {r0-r12,pc}^   ; Restore registers and return.

This code could be modified to co-operate with Multi-ICE semihosting as follows:

; r0 = 1 if SWI handled
    CMP r0, #1                ; Test if SWI has been handled.
    LDMFD sp!, {r0}           ; Unstack SPSR...
    MSR spsr_cxsf, r0         ; ...and restore it.
    LDMFD sp!, {r0-r12,lr}    ; Restore registers.
    MOVEQS pc, lr             ; Return if SWI handled.
    MOVS pc,lr                ; Fall through to Multi-ICE
                              ; interface handler.

The $semihosting_vector variable must be set up to point to the address of Semi_SWI. The instruction at Semi_SWI never gets executed because Multi-ICE returns directly to the application after processing the semihosted SWI (see Figure 5.2).


Using a normal SWI return instruction ensures that the application does not crash if the semihosting breakpoint is not set up. The semihosting action requested is not carried out and the handler simply returns.

You must also be careful if you modify $semihosting_vector to point to the fall-through part of the application SWI handler. If $semihosting_vector changes value before the application starts execution, and semihosted SWIs are invoked before the application SWI handler is installed, an unknown watchpoint error will occur.

Figure 5.2. Semihosting with breakpoint

The error occurs because the vector table location for the SWI has not yet had the application handler installed into it and might still contain the software breakpoint bit pattern. Because the $semihosting_vector address has moved to a place that cannot currently be reached, Multi-ICE no longer knows about the triggered breakpoint. To prevent this from happening, you must change the contents of $semihosting_vector only at the point in your code where the application SWI handler is installed into the vector table.


If semihosting is not required at all by an application, this process can be simplified by setting $semihosting_enabled to 0.

Copyright © 1999-2001 ARM Limited. All rights reserved.ARM DUI0058D