RISC OS Open
A fast and easily customised operating system for ARM devices
ROOL
Home | News | Software | Bugs | Bounties | Forum | Documents | Photos | Contact us
Account

SWI Introduction

Programmer's Reference Manuals
» Part 1 - Introduction
» Introduction to SWIs
» SWI Introduction

Overview

**S**oft**w**are **I**nterrupts, or SWIs for short, are a set of powerful instructions to allow developers to interact with the Operating System, without allowing any direct control in Supervisor Mode. The process of using a SWI is as follows:

  1. Program issues a specific SWI instruction
  2. ARM leaves the program and jumps to a fixed location in memory where there is normally a branch instruction into the RISC OS kernel
  3. Examine SWI instruction and determine the particular OS routine to be run
  4. Call the OS routine as specified by the SWI
  5. Once finished, return back to program

A SWI consists of a unique name, number and usually requires parameters to be passed.

Because RISC OS is modular, different modules implement specific SWIs.

SWI names and numbers

A SWI can be used by either referring to its unique name or number. The 24-bit number, known as the SWI number, is used by RISC OS to identify the routine.

The exact method that RISC OS uses to decode the SWI is unimportant. As long as the correct SWI name or number along with any parameters (if required) are used, then the correct result will be returned.

It is strongly advised to use the SWI names when calling SWIs as it greatly improves readability and helps create code that can be updated with ease.

It is also important to note that SWI names are case sensitive. They must be typed exactly as documented, otherwise RISC OS will not identify the SWI, and an error will be returned. The names usually follow Camel Case rules, e.g. “BinaryToDecimal”.

A list of SWIs broken down by Module is available here.

SWI numbers

A SWI instruction is allocated a unique number. 24-bits are used to specify the SWI number (0 – &FFFFFF), although only SWIs from &40000 (bit 19 must be set) upwards are available for 3^rd^ party use, as the others are assigned for internal use by RISC OS (although only a small percentage are currently used).

Modules can also provide their own SWIs, and must provide unique SWI numbers. This feature allows for SWIs that perform related functions to be grouped together as part of a module, making it a modular Operating System.

If a program executes a SWI that is not recognised, the OS calls a special routine called the ‘Unused SWI Vector’ or UKSWIV vector for short. This usually returns the generic ‘No such SWI’ error message, however, it is possible for an application to claim this vector and if the SWI number is recognised by the program perform the appropriate task.

24-bit Address field

The 24-bit SWI number consists of the following:

Bits Identifier Information
0 – 5 Chunk Offset Number Identify individual SWIs in a chunk
6 – 16 Chunk Number Specifies a block of 64 consecutive SWIs for use by application or module
17 Error Flag (X bit) Determine the action taken on errors
18 – 19 SWI Group Specifies which part of the system implements the SWI. Possible values are shown in the table below
20 – 23 OS Flag Specify which OS the SWI expects to execute the SWI. RISC OS requires this bit to be zero

SWI Group

Bit 19 Bit 18 Meaning
0 0 Operating System
0 1 Operating System modules
1 0 Third party applications
1 1 User applications

Naming convention

SWI names are broken into two discrete parts separated by the underscore character ‘_’. The prefix specifies which part of the system will deal with the SWI. The prefix name usually specifies by the module which implements the SWI. e.g. Wimp, Font, ADFS, FileCore.

The suffix specifies the function of the SWI, and when added to the prefix specifies the Chunk Name. The chunk name is usually the name of the module that provides the SWI, although it is dependant on the name when registering the SWI. Some examples are shown below:

SWI name Chunk Name SWI Function
OS_ReadSysInfo OS ReadSysInfo
FileCore_FreeSpace FileCore FreeSpace
PCI_RAMFree PCI RAMFree

Parameters and results

Parameters are used to pass values to and from the SWI routines. The ARM registers are used to pass information as required. SWIs may use R0 to R9 inclusive, although there is a restriction to using only R0 to R7 via BASIC, although this is rarely a problem as most SWIs seldom use more than 4 or 5 registers.

When a number, character or address needs to be passed to/from a SWI, the actual data itself is passed.

When a string or a large amount of data needs to be passed, a pointer to the data is used instead.

Error handling

As you would expect, RISC OS provides error handling facilities for SWIs. There are two possible steps to the error checking process:

  1. Check if an error occurred during the execution of the SWI routine
    • If an error has been generated by the SWI routine, the V flag is set, and R0 points to an error block on exit, and then proceed to the second step in the error checking process
    • If no error has been generated by the SWI routine, the V flag is clear on exit
  2. Check if the X bit (bit 17) of the SWI instruction was set prior to entering the SWI routine
    • If the X bit was set before the routine, then RISC OS returns control back to the progam, which must then deal with the error. The V flag remains set, and R0 points to an error block on exit (known as error-returning)
    • If the X bit was clear before the routine, then RISC OS deals with the error itself. It does this by passing the error to the error handler used by the program (known as error-generating)

The state of the X bit determines how RISC OS deals with an SWI error. It is sometimes useful for RISC OS to deal with an error, while other times it is best if your own program deals with an error. And error-returning SWI can be specified by two different methods:

  • Add the value &20000 to the SWI number called
  • Add the letter ‘X’ in front of the SWI name; thus OS_WriteC becomes XOS_WriteC

As the most common method of using SWIs is by name; prepending the letter X to the name is the most common approach.

A detailed summary of how RISC OS handled Error-generating SWIs is provided below, although it is not necessary to understand this low-level information.

  1. RISC OS informs modules of the error using OS_ServiceCall (service number 6) so that it can tidy up. e.g. close files, and so on, before RISC OS handles the error
  2. RISC OS then calls the error vector (ErrorV), so it may tidy up (if required). The vector can be claimed, however, the error handler must deal with the error, and not your progam

Error numbers

If an error has been generated, R0 points to an error block that identifies the type of error.

The format of the error block is described here

The error number contained as part of the error block specifies the type of error. The error number is a 32-bit number, and is divided into three discrete parts:

  • The bottom byte is known as the basic error number
  • The middle two bytes identifies the cause of the error
  • The top byte contains flags; as detailed below
Bit Meaning if set
24 – 29 Sometimes used as a sub-error indicator if bit 31 is set. e.g. ADFS uses them to identify the type of disc error
30 Defined to be clear, so can be safely used by developers to flag internal errors
31 Specifies a serious error, such as a hardware exception or floating point exception. In these cases, different error number ranges are used

Error handling with vectored SWIs

When calling SWIs normally, it is safe to assume that the V flag of the return address (R14_svc) has been cleared, before a SWI routine is entered. This ensures that return address in the correct format to indicate that no errors occurred.

However, it is not safe to assume this with SWI routines that are vectored. This is because any of these routines may have been called using OS_CallAVector, which does not clear the V flag.

When claiming a vector and replacing a SWI routine, the replacement routine must not assume the state of the V flag. It must explicitly clear the V flag if there was no error, or set it there was an error.

Generating errors

It is possible to generate an error by calling OS_GenerateError. The routine does not return.

Writing system extension code

When writing system extension code, such as a module or interrupt handler, it is vital that it does not generate errors. This is because users expect it to ‘just work’. When issuing SWIs in system extension code, they must always have their X bit set. i.e. either add the value &20000 to the SWI number, or add the letter ‘X’ in front of the SWI name.

The exception to the rule is when reporting exception-type errors. i.e. when bit 31 of the error number is set (indicating a serious error).

Allocating SWIs

SWIs names and numbers can be allocated through RISC OS Open using their Allocate tool (RISC OS software only) and is available here.

When registering a SWI, a Chunk name must be provided, and this will be used as part of the SWI name. e.g. __ChunkName___Function.

Revised on January 26, 2010 14:43:32 by Jeff Doggett (257)? (127.0.0.1)
Edit | Back in time (3 revisions) | See changes | History | Views: Print | Source | Linked from: Introduction To SWIs

Search the Wiki

Social

Follow us on and

Commercial use

For commercial enquiries, please contact the owners of RISC OS, Castle Technology Ltd.

ROOL Store

Buy RISC OS Open merchandise here, including SD cards for Raspberry Pi and more.

Donate! Why?

Help ROOL make things happen – please consider donating!

Navigation

  • Home Page
  • All Pages
  • Recently Revised
  • Authors
  • Feeds
Site design © RISC OS Open Limited 2011 except where indicated
The RISC OS Open Instiki theme is based on Insitki's default layout

Valid XHTML 1.0  |  Valid CSS

Instiki 0.19.1(MML+)
This site runs on Rails

Hosted by Arachsys