This note describes the new or revised SWIs in the StrongARM-aware version
of RISC OS, and gives some guidance on use.


                          CHANGES TO EXISTING SWIS
                          ========================
                       
OS_MMUControl (page 5a-70)
--------------------------

    This SWI has a new reason code, to support platform independent cache
    and/or TLB flushing:

OS_MMUControl 1 (SWI &6B)
-------------------------

    Cache flush request
    
On entry
    R0 = reason code and flags
           bits 0-7  = 1 (reason code)
           bits 8-28 reserved (must be zero)
           bit 29 set if flush of single entry, else complete flush
           bit 30 set if processor TLBs are to be flushed
           bit 31 set if processor caches are to be flushed
    R1 = logical address, if R0 bit 29 set

On exit
    R0,R1 preserved

Interrupts
    Interrupt status is not altered
    Fast interrupts are enabled

Processor mode
    Processor is in SVC mode

Re-entrancy
    SWI is not re-entrant
    
Use
    This call implements platform independent cache and/or TLB flushing.
    
    WARNING: This SWI reason code is only intended for occasional, unavoidable
             requirements for cache/TLB flushing. You should respect the
             performance implications of this SWI reason code, in a similar
             way to SWI OS_SynchroniseCodeAreas.
             
    Currently, bit 29 is ignored, so that only whole flushing of caches
    and/or TLBs are supported. A cache will be cleaned before flushing,
    where the processor supports a write-back cache.

    This reason code is not re-entrant. Interrupts are not disabled during
    the flush, so the cache or TLB flush can only be considered to be complete
    with respect to logical addresses that are not currently involved in
    interrupts.


OS_File 12, 14, 16 and 255 (page 2-40)
--------------------------------------
If R3 bit 31 is set on entry, the file being loaded will be treated as code,
and the relevant area will be synchronised using OS_SynchroniseCodeAreas if
necessary.

A filetype for Code (&F95) has been allocated, with the intention that it
be a parallel of Data (&FFD), and when it is loaded a synchronise is
automatically performed. However this functionality has _not_ been implemented
in RISC OS 3.70; you will still need to set bit 31 as described above.


DMA (page 5a-83)
----------------
The DMA Manager now marks pages uncacheable for both transfers from device
to memory and transfers from memory to device. This is to ensure StrongARM's
write-back cache is cleaned before the transfer starts.



                             NEW SERVICE CALLS
                             =================

Service_UKCompression (Service call &B7)
----------------------------------------

    An application that may need unsqueezing/patching has just been loaded
    
On entry
    R0 = subreason code
           0 -> first pass (unsqueeze)
           1 -> second pass (patch)
           all other codes reserved
    R1 = &B7 (reason code)
    R2 = load address
    R3 = size
    R4 = execute address
    R5 = filename (as passed to FileSwitch, not canonicalised)

On exit
    R1 preserved to pass on, or 0 to claim if you know you have performed
    all required unsqueezeing/patching for this pass.
    R3 may be modified to indicate an altered size (eg after unsqueezing)
    R4 may be modified to specify an new execute address
    Other registers preserved

Use
    This service call is passed around when an Absolute (&FF8) file is run.
    The sequence of events is as follows.
    
      1) The image is loaded.
      2) If it does not contain an unsqueezed AIF header, then
         Service_UKCompression 0 is issued.
      3) Service_UKCompression 1 is issued.
      4) OS_SynchroniseCodeAreas is called.
    
    Therefore unsqueezers and patchers need not do any synchronisation
    except that necessary for their internal working (they may want to alter
    some code, synchronise, and call it before returning from the service
    call).
    
    Two modules are supplied with RISC OS 3.7 that use this service call:
    
        UnsqueezeAIF will unsqueeze squeezed AIF images on the first pass, and
        squeezed non-AIF images by code modification (so the unsqueeze will
        not occur until after stage 5 above)
    
        AppPatcher will patch squeezed and unsqueezed AIF images containing
        certain common code sequences that are known to fail on StrongARM.

    Scanning an application for code sequences is a relatively slow operation.
    Therefore a bit has been allocated in the AIF header to indicate that
    a program is "StrongARM-ready". If bit 31 of the 13th word of the AIF
    header (ie bit 31 of location &8030 in the loaded image) is set, the
    patching stage will be skipped (in RISC OS 3.7 by AppPatcher claiming
    the service call and doing nothing; in a future version of RISC OS
    FileSwitch may not issue the service call). The program will still be
    automatically unsqueezed; it is recommended that you continue to use the
    existing Squeeze utility provided with Acorn C/C++, and rely on the
    operating system to unsqueeze the image for you.
   
   
Service_ModulePreInit (Service call &B9)
----------------------------------------

    A module is about to be initialised
    
On entry
    R0 = module address
    R1 = &B9 (reason code)
    R2 = module length

On exit
    R1 preserved to pass on

Use
    This service is called just before a module is initialised. When a
    module is *RMLoaded:
    
       1) The module is loaded into memory
       2) The module is unsqueezed if necessary
       3) Service_ModulePreInit is called
       4) OS_SynchroniseCodeAreas is called
    
    This service call is intended to allow run-time patching of modules.
    
    
                                  NEW SWIS
                                  ========

OS_PlatformFeatures (SWI &6D)
-----------------------------

    Determine various features of the host platform

On entry
    R0 = reason code (bits 0-15) and flags (bits 16-31, reason code specific)
    Other registers depend upon the reason code

On exit
    Registers depend upon the reason code

Interrupts
    Interrupt status is unaltered
    Fast interrupts are enabled
    
Processor mode
    Processor is in SVC mode

Re-entrancy
    SWI is re-entrant

Use
    This new SWI is used to determine various feaures of the platform that the
    application or module is running on.

    The particular action of OS_PlatformFeatures is given by the reason code in
    bits 0-15 of R0 as follows:
    
        R0    Action
        0     Read code features


OS_PlatformFeatures 0 (SWI &6D)
-------------------------------

    Read code features

On entry
    R0 = 0 (reason code); all flags are reserved, so bits 16-31 must be clear

On exit
    R0 = bit mask of features:
           Bits     Meaning
           0        Must tell OS when code areas change (by calling
                    OS_SynchroniseCodeAreas)
           1        Enabling, then immediately disabling interrupts will _not_
                    give interrupts a chance to occur
           2        Must be in 32 bit mode to read hardware vectors
           3        Storing PC to memory (eg with STR or STM) stores PC+8
                    rather than PC+12
           4        Data aborts occur with 'full early' timing (ie. as defined
                    by ARM architecture 4)
                                
   If bit 1 of R0 set then                             
     R1 -> routine to call (with BL) between IRQ enable & disable.

Use
    This call determines features of the host processor's instruction set.
    
    Platforms running ARM 6 or 7 cores will return with R0 bits 0-4 clear;
    platforms running StrongARM will return with bits 0-4 set in RISC OS 3.7
    (but bit 2 should in fact be clear). For compatibility with older
    versions of RISC OS, you should call this SWI in the X form; if V is set
    on return and the error is 'SWI not known', then this can be taken as
    equivalent to a return with R0 bits 0-4 clear. Note that the easiest way
    to deal with the PC+8/PC+12 issue across all platforms is to make sure
    that the code is valid in either case (typically with judicious use of
    NOPs).
    
    The routine pointed to by R1 is suitable for calling from any 26-bit mode;
    it preserves all flags and registers, and is reentrant.


OS_SynchroniseCodeAreas (SWI &6E)
---------------------------------

    Inform the OS that code has been altered

On entry
    R0 = flags
           bit 0 clear  Entire address space to be synchronised.
           bit 0 set    Address range to be synchronised.
           bits 1-31    Reserved

    If R0 bit 0 is set then:
        R1 = low address of range (word aligned)
        R2 = high address (word aligned, _inclusive_)

On exit
    R0-R2 preserved

Interrupts
    Interrupt status is not altered
    Fast interrupts are enabled

Processor mode
    Processor is in SVC mode

Re-entrancy
    SWI is not re-entrant

Use
    This new SWI informs the OS that code has been newly generated or
    modified in memory, before any attempt is made to execute the code.

    WARNING: This SWI is only intended for synchronisation with unavoidable
             use of dynamic code, because of the potential for large
             performance penalties. There is no longer any justification in
             RISC OS applications for frequent code modification. This call
             must never be used in an interrupt routine. Examples of
             reasonable use include one-off loading, relocation etc. of
             subsidiary code or libraries.
     
    When using this SWI, you should use the ranged variant wherever possible,
    in order to minimise the performance penalty.
    
    The call may take a long time to return (up to around 0.5ms), so it should
    not be called with interrupts disabled.

    For compatibility with older versions of RISC OS, you should either have
    determined (with OS_PlatformFeatures) that this SWI should not be called,
    or always call this SWI in the X form, and ignore any error returned. On
    platforms that do not require code synchronisation (as indicated by
    OS_PlatformFeatures 0), OS_SynchroniseCodeAreas will do nothing.

    Note that standard loading of applications or modules (and the standard C
    overlay system) are automatically handled by the OS, and do not require
    synchronisation. This may be defeated by custom squeezing, failure to use
    a standard AIF header for applications, and so on.


OS_CallASWI (SWI &6F)
---------------------

    Call a run-time determined SWI

On entry
    R0-R9 as required for target SWI
    R10 = target SWI number

On exit
    R0-R9 as defined by target SWI
    R10 preserved

Interrupt status
   As defined by target SWI

Processor mode
   As defined by target SWI

Re-entrancy
   As defined by target SWI

Use
    This new SWI allows a target SWI number to be determined at run time, and
    passed in a register. This removes the need for a common idiom of
    dynamic code, in language library SWI veneers for example. In an APCS-R
    library, OS_CallASWIR12 may be more appropriate (see below).

    Note that OS_CallASWI is merely an alias for calling the target SWI.
    It has no entry/exit conditions of its own, except for the special
    use of R10. To call a target SWI with X bit set, us the X form of
    the SWI number in R10; there is no distinction between OS_CallASWI
    and XOS_CallASWI.

    You cannot call OS_CallASWI or OS_CallASWIR12 via OS_CallASWI, since there
    is no defined final target SWI in this case.

    You cannot usefully call OS_BreakPt or OS_CallAVector using OS_CallASWI,
    as OS_CallASWI will corrupt the processor flags before entering the
    target SWI.
    
    For future compatibility, you should always use this SWI in preference
    to any local construction for calling a SWI by number. For compatibility
    with older versions of RISC OS, a new CallASWI module will be made available
    (see below).
    
    Note that this SWI calling mechanism is almost certainly faster than
    any other alternative implementation, including the original _kernel_swi
    and _swix code contained in older versions of the SharedCLibrary. The
    new SharedCLibrary now simply uses OS_CallASWIR12 for _kernel_swi and
    _swix.
    
    OS_CallASWI cannot be called from BASIC as BASIC only passes registers
    R0-R7 via its SYS instruction. It would not be useful anyway.


OS_AMBControl (SWI &70)
-----------------------

    This SWI is for system use only; you must not use it in your own code.


OS_CallASWIR12 (SWI &71)
------------------------

    Call a run-time determined SWI

On entry
    R0-R9 as required for target SWI
    R12 = target SWI number

On exit
    R0-R9 as defined by target SWI
    R12 preserved

Interrupt status
   As defined by target SWI

Processor mode
   As defined by target SWI

Re-entrancy
   As defined by target SWI

Use
    This call is identical to OS_CallASWI, except that it uses R12 to specify
    the target SWI. This may be more convenient in some environments. In
    particular under APCS-R, R10 is the stack limit pointer, which must be
    preserved at all times; if a SWI called using OS_CallASWI were to abort
    or generate an error the run-time library would usually examine R10
    and decide that it had no stack to handle the abort or error. Therefore
    APCS-R libraries must use OS_CallASWIR12 (R12 being a scratch register
    under APCS-R).


                      THE CALLASWI MODULE
                      ===================

The CallASWI module provides support under RISC OS 3.1, 3.5 and 3.6 for
the following SWIs:

              OS_CallASWI
              OS_CallASWIR12
              OS_PlatformFeatures
              OS_SynchroniseCodeAreas

This will enable application programmers and library writers to use the
new calls freely without any worries about backwards compatibility. There
is no performance penalty for the use of these SWIs via the CallASWI
module. One slight caveat is that older machines will not know the
_names_ of these SWIs; they would have to be called by number from BASIC.
