Introduction to the StrongARM Revision 3, 04-Oct-96
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
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.
Note that the *Load command calls OS_File 255 with bit 31 of R3 set, so no synchronise is required. This is to aid backwards compatibility; if no synchronisation is required, then use OS_File 255 directly.
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
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)
R1 preserved to pass on, or 0 to claim if you know you have performed
all required unsqueezeing/patching for this pass.
1. The image is loaded.
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
R0 = module address R1 = &B9 (reason code) R2 = module length
1. The module is loaded into memory
This service call is intended to allow run-time patching of modules.
OS_PlatformFeatures (SWI &6D)
Determine various features of the host platform
R0 = reason code (bits 0-15) and flags (bits 16-31, reason code specific) Other registers depend upon the reason code
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
R0 = 0 (reason code); all flags are reserved, so bits 16-31 must be clear
If bit 1 of R0 set then R1 -> routine to call between IRQ enable & disable.
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. 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. It should be called as follows
LDRR0, irqroutine ; Load address previously stored in workspace MOVR14, PC; Get return address of PC+8 MOVPC, R0 ; Call routine ... ; Code returns here
OS_SynchroniseCodeAreas (SWI &6E)
Inform the OS that code has been altered
R0 = flags bit 0 clearEntire address space to be synchronised. bit 0 setAddress range to be synchronised. bits 1-31Reserved
If R0 bit 0 is set then:
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
R0-R9 as required for target SWI R10 = target SWI number
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
R0-R9 as required for target SWI R12 = target SWI number
THE CALLASWI MODULE
The CallASWI module provides support under RISC OS 3.1, 3.5 and 3.6 for the following SWIs:
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.