4.8.2. Adding an application SWI handler when using Multi-ICE

Many applications require their own SWI handlers as well as using semihosting SWIs. You must do this so that the application SWI handler cooperates with the Multi-ICE semihosting mechanism as follows:

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

  2. For standard semihosting, modify the value of semihosting_vector to point to a location that is only reached if your handler does not recognize the SWI, or recognizes it as a semihosting SWI.

  3. For DCC semihosting, install the application SWI handler on the SWI vector. When a SWI the application does not recognize occurs, branch to semihosting_dcchandler_address+12 with the processor state as it was on entry to the SWI handler. The DCC semihosting handler executes the request and returns to the calling code.

For example, a particular SWI handler might detect if it has failed to handle a SWI and branch to an error handler (see the ADS documentation for further details of writing SWI handlers). An example of a basic exception handler is shown in Example 4.3.

Example 4.3. Basic SWI 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_cf, r0          ; ...and restore it.
    LDMFD sp!, {r0-r12, pc}^ ; Restore registers and return.

You can modify this code for use in conjunction with Multi-ICE start-stop semihosting as shown in Example 4.4.

Example 4.4. SWI handler with Multi-ICE link

                            ; r0 = 1 if SWI handled
    CMP r0, #1              ; Test if SWI has been handled.
    LDMFD sp!, {r0}         ; Unstack SPSR...
    MSR spsr_cf, r0         ; ...and restore it.
    LDMFD sp!, {r0-r12, lr} ; Restore registers.
    MOVEQS pc, lr           ; Return if SWI handled.
Semi_SWI
    MOVS pc, lr

You must then set up the semihosting_vector with the address of Semi_SWI. The instruction at this address is never actually executed because the Multi-ICE DLL returns directly to the application after processing the semihosted SWI. Using a normal SWI return instruction ensures that the application does not crash if the semihosting breakpoint is not set up.

If the application is linked with the semihosted ARM C library, and therefore uses the C library startup code, you must change the contents of semihosting_vector just before the application installs its own handler, typically by setting a breakpoint in the main code. This is because, if semihosting_vector is set to the fall-through part of the application SWI handler before the application starts execution, the semihosted SWIs that are called by the library initialization can trigger an unknown watchpoint error. At this point, the SWI vector has not yet had the application handler written to it, and might still contain the software breakpoint bit pattern. This triggers a breakpoint that the Multi-ICE DLL does not know about because the semihosting_vector address has moved to a place that cannot currently be reached.

Note

If semihosting is not required by your application, including the startup code, you can simplify this process by setting semihosting_enabled to zero.

You must take care when moving an application that previously ran in conjunction with the Angel debug monitor onto a Multi-ICE system. On Angel debug monitor systems, application SWI handlers are typically added by moving and adjusting the contents of the Angel installed SWI vector to another place, and installing the application SWI handler into the SWI vector. This method does not apply to the Multi-ICE DLL because there is no instruction to move out of the SWI vector, and no code to jump to. Therefore, when moving an application onto a Multi-ICE based system, you must convert to the Multi-ICE way of installing the application and semihosted SWI handlers.

Copyright © 1998-2002 ARM Limited. All rights reserved.ARM DUI 0048F
Non-Confidential