RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

Memory management


Introduction

This chapter describes changes in memory management made in RISC OS 3.5. These changes have been caused by the changes in the underlying hardware used in the new architecture.

Memory management now incorporates the following:

  • Up to 256MB DRAM and 2MB VRAM of memory is allowed.
  • Direct memory access (DMA) control is improved.
  • Any second processor card can claim a chunk of memory.
  • Physical RAM allocation does not have to be contiguous.
  • Page table allocation is added to support the memory management unit (MMU) in newer ARM processors.
  • The logical memory map is expanded due to the 32 bit address space.

Running 32 bit code

The new generation of ARM chips used provide 26 bit processor modes (which are backwards compatible with the ARM2 and ARM3), and 32 bit processor modes. With one exception, RISC OS 3.5 only supports 26 bit processor modes. You must not execute code in 32 bit processor modes. If you try to do so, you may get unpredictable crashes, especially if you try to run the code in address space over 64M.

The exception mentioned above is if you are writing handlers that claim a hardware vector. For details, see the chapter entitled Hardware vectors.

Overview

Free memory pool

In RISC OS 2 and 3 memory management was divided between the kernel and the Wimp.

  • The kernel ordered the memory into dynamic areas and an application space.
  • The Wimp managed a free pool and multiple applications mapped in turn into the same application space; it was responsible for constructing and managing tasks in the desktop. It grew or shrank tasks by mapping a free pool into application space above the task, and then moving the boundary between the two.

RISC OS 3.5 supports amounts of memory so large that the free pool may now be too large to map into application space.

  • The kernel is therefore now responsible for managing the free pool memory, which it keeps in a new dynamic area, known as the free pool (area number 6).
  • The Wimp's operation is simplified, as it no longer needs to maintain its own free pool.
How the free pool operates

When you grow or shrink dynamic areas other than the free pool, the free pool is used as follows:

  • If an area other than the free pool is grown, memory is taken from the free pool, if any exists. The current application is not notified of this.

    If having shrunk the free pool to zero size, there is still not enough memory for the growth, the kernel attempts to remove pages from the application space as it does under existing versions of RISC OS.

  • If an area other than the free pool is shrunk, the pages recovered are added to the free pool. The current application is not consulted.

The Wimp grows or shrinks tasks by shrinking or growing (respectively) the free pool itself:

  • If the free pool is grown, pages are taken from application space to put in it. The current application is consulted beforehand.
  • If the free pool is shrunk, the recovered pages are added to application space. The current application is consulted beforehand.

The tasks themselves must still change their memory allocation using current RISC OS interfaces (as before), rather than changing the size of the free pool.

Dynamic areas

In RISC OS 2 and 3 the main kernel interface for memory management was OS_ChangeDynamicArea, with which you could resize the predefined dynamic areas. This SWI then called other modules, depending on which dynamic area was being resized. This left no flexibility, and in particular, there were no facilities for creating other dynamic areas. This meant the existing areas were often used illicitly by applications which - once they quit - would leave the area badly fragmented.

Other memory related services were not available. For example it was not possible to find out what memory was available on the system without knowing a great deal about the platform.

From RISC OS 3.5 onwards the new SWI OS_DynamicArea is provided for you to create dynamic areas, get information on them, and delete them. This allows you to claim and release your own area of memory that is managed by hardware (and so does not suffer from garbage), and is persistent. This is far preferable to illicitly using (say) a part of the RMA or sprite area, as has been common practice.

You should still use OS_ChangeDynamicArea just as before to alter the size of dynamic areas.

As all operations on dynamic areas work in physical page numbers you cannot map anything other than RAM pages (DRAM and VRAM) into a dynamic area. In particular you cannot map in the extension to the existing expansion card bus space, known as the EASI space.

Technical Details

Logical memory map

Base Description Size
2.5G More dynamic areas 1.5G Public5
2G Copy of physical space 512M Private
64M Dynamic areas 2G-64M Public5
56M ROM 8M Private
55M Reserved for 2nd processor control registers 1M Private
54M Reserved for future expansion 1M Private
53M VIDC20 1M Private
52M Reserved for VIDC1 emulation 1M Private
48M I/O space 4M Private4
44M Reserved for system use 4M Private
33M RMA 11M Public3
31M+64K Reserved for fake screen (480K) 2M-64K Private
31M+32K "Nowhere" 32K Private
31M Cursor / system space / sound DMA 32K Private
30M+8K Soft CAM map 1M-8K Private
30M Undefined stack 8K Public2
28M+8K System heap 2M-8K Private
28M SVC stack 8K Public2
32K Application space 28M-32K Public
16K Scratch space 16K Public1
0 System workspace 16K

Notes about the logical memory map:

  1. The public1 area may be used by any module that is not
    • used in an IRQ routine
    • used if you call something else that might also use it.

    An example client would be FileCore using the scratch space to hold structures while working out how to allocate some free space. Another example would be the Filer using the scratch space to hold structures for OS_HeapSort.

  2. The public2 areas can be assumed to have their lowest address on a 1MB boundary (being descending stacks). An exception will occur if they are accessed beyond this point. The exact location of these stacks should not be assumed.
  3. The public3 area should not assume the location of the RMA or its maximum size. However it will be in the lower 64MB (ie it can execute 26 bit code).
  4. The private4 area is private, and used for I/O except where device drivers export hardware addresses.
  5. The public5 areas can be used by a client to make its own dynamic area.

Memory terminology

There are three ways of referring to memory:

Physical address

This refers to the address of the memory in the physical address space, as presented by the ARM chip to IOMD.

Logical address

This refers to the logical address space that the ARM processor core presents to the ARM chip memory management unit. This is controlled by the operating system.

Physical page number

This is an arbitrary number assigned to each page of RAM physically present in the computer.

Page blocks

Several interfaces use page blocks to pass round lists of addresses and/or pages. These are tables of 12-byte records (so a page block is 12n bytes long, where n is the number of records). Each record has the following format:

Offset Meaning
0 Physical page number
4 Logical address
8 Physical address

New SWIs

The following new SWIs have been created. They are defined in full at the end of this chapter.

  • OS_DynamicArea is used for the control, creation and deletion of dynamic areas. R0 provides a reason code which determines which operation is performed.
  • OS_Memory performs miscellaneous operations for memory management. Again, R0 provides a reason code which determines which operation is performed.

Changes to existing SWIs

OS_ChangeDynamicArea

You can now alter the space allocation of the free pool (see Free memory pool) by setting R0 to 6 on entry.

OS_SetMemMapEntries

With the new architecture you must use -1 to indicate that a page should become inaccessible.

OS_ReadDynamicArea

In RISC OS 3, if bit 7 of the dynamic area number is set then R2 will be returned with the maximum area size.

This has changed slightly from RISC OS 3.5 onwards.

If the dynamic area number passed in is greater than or equal to 128 then R2 is returned as the maximum size of the dynamic area. Also, if the dynamic area number passed in is between 128 and 255 inclusive then the information is returned for the area whose number is 128 less than the passed-in value.

The net result is that for old dynamic area numbers (0 - 5) the functionality is unchanged, but the number-space impact of the interface is minimised.

Also, if R0 is -1 on entry, it returns the following information on application space:

R0 = base address (&8000)
R1 = current size (ie for current task)
R2 = maximum size (<= 28MB-32kB in current implementation)

OS_Heap 0

RISC OS 2 and 3 place strong restrictions on the heap: the base of the heap as specified in R1 must be word-aligned and less than 32Mbytes, and the size of the heap must be a multiple of 4 and less than 16Mbytes.

From RISC OS 3.5 onwards the only restrictions are that the base of the heap must be word-aligned, and the size must be a multiple of 4 bytes.

Wimp_TransferBlock

In earlier operating systems Wimp_TransferBlock put all used task memory into the application space, and then copied the relevant parts over. It cannot do this any more, as the total used task memory may not fit into application space.

The algorithm used by this call has accordingly been changed, and the opportunity taken to improve its performance. The call still has the same entry and exit conditions.

Wimp_ClaimFreeMemory

Because the Wimp no longer maintains control of the free pool, the call Wimp_ClaimFreeMemory has had to be modified; it simulates its previous behaviour as well as possible. In general, applications written for older versions of RISC OS will work unmodified; but you should be aware that the call may now return addresses that use more than 26 bits. This will be a problem if your old applications use any of the top 6 bits for their own purposes.

Using this call in new applications is deprecated. You should instead use OS_DynamicArea to create your own dynamic area.

Cache_... SWIs Cache_Control onwards)

These ARM3-specific SWIs are not implemented from RISC OS 3.5 onwards.

Changes to existing * Commands

*Cache

*Cache now switches both cacheing and write buffering on and off.

Dynamic area handler routines

When you create a dynamic area with the new SWI OS_DynamicArea 0 you can also specify the address of a dynamic area handler routine, which is called when the size of the area is being changed. The routine is called in SVC mode; the reason for calling it is given in a reason code held in R0. The section below gives the entry and exit conditions of the routine for each valid reason code.

When called, OS_ChangeDynamicArea is working. It rejects requests to resize dynamic areas. You should not use SWIs which resize dynamic areas, for example using OS_Module to claim some workspace. File operations should be normally avoided, although I/O on an existing file is usually safe.

PreGrow (0)

Issued just before pages are moved to grow an area

On entry

R0 = 0 (reason code)
R1 = pointer to a page block, the physical page numbers of which are set to -1; or undefined if bit 8 of the areas flags was clear on creation (see OS_DynamicArea 0)
R2 = number of entries in page block (i.e. number of pages area is growing by)
R3 = amount area is growing by, in bytes (i.e. R2 × R5)
R4 = current size of area, in bytes
R5 = page size, in bytes
R12 = pointer to workspace

On exit

All registers preserved

Use

This reason code is issued when a call to OS_ChangeDynamicArea results in an area growing, before any pages are actually moved.

You can request that specific pages be used for growing the area by filling in their page numbers in the page block. If you do so, you must specify all the pages. The first entry in the page block corresponds to the lowest memory address of the extension, and the last entry in the page block the highest memory address.

You can prevent the area changing size by returning an error. R0 should point to a standard RISC OS error block, or be set to zero for a generic error message to be used. You should then return with the V flag set.

PostGrow (1)

Issued just after pages are moved to grow an area

On entry

R0 = 1 (reason code)
R1 = pointer to a page block, only the physical page numbers of which are defined; or undefined if bit 8 of the areas flags was clear on creation (see OS_DynamicArea 0)
R2 = number of entries in page block (i.e. number of pages area grew by)
R3 = amount area grew by, in bytes (i.e. R2 × R5)
R4 = new size of area, in bytes
R5 = page size, in bytes
R12 = pointer to workspace

On exit

All registers preserved

Use

This reason code is issued when a call to OS_ChangeDynamicArea results in an area growing. It is called after the PreGrow reason code has been issued successfully and the memory pages have been moved. It provides the handler with a list of which physical pages have been moved into the area.

PreShrink (2)

Issued just before pages are moved to shrink an area

On entry

R0 = 2 (reason code)
R3 = amount area is shrinking by, in bytes
R4 = current size of area, in bytes
R5 = page size, in bytes
R12 = pointer to workspace

On exit

R3 = amount area can shrink by, in bytes (must be <= R3 on entry)
All other registers preserved

Use

This reason code is issued when a call to OS_ChangeDynamicArea results in an area shrinking, before any pages are moved. You can limit the amount of memory moved out of the area. If the permitted shrinkage you return is a non-page multiple, it will be rounded down to a page multiple.

You can prevent the area changing size by returning an error. R0 should point to a null terminated error message, or be set to zero for a generic error message to be used. R3 should be zero, to show that no shrinkage is possible. You should then return with the V flag set.

PostShrink (3)

Issued just after pages are moved to shrink an area

On entry

R0 = 3 (reason code)
R3 = amount area shrunk by
R4 = new size of area, in bytes
R5 = page size, in bytes
R12 = pointer to workspace

On exit

All registers preserved

Use

This reason code is issued when a call to OS_ChangeDynamicArea results in an area shrinking. It is called after the PreShrink reason code has been issued successfully even if the memory pages cannot be moved.

Sequence of actions when SWI OS_ChangeDynamicArea is called

The system stack is used for the page block passed to the PreGrow routine, where required. As a consequence there is a limit to the amount that an area can be grown by at one time. To get round this problem an area grow request of a large amount will be performed in several steps. If one of these steps fails then the grow will terminate early with the area grown by however much was achieved, but not by the full amount requested.

Two new service calls are used; Service_PagesUnsafe and Service_PagesSafe. These are issued around page swapping to inform any DMA subsystems (eg IOMD DMA or second processor) that some pages are being swapped around.

Service calls


Service_PagesUnsafe
(Service Call &8E)

Pages specified are about to be swapped for different pages

On entry

R1 = &8E (reason code)
R2 = page block filled in by the PreGrow routine, with the two address fields also filled in
R3 = number of pages in page block

On exit

All registers preserved

Use

This service call informs recipients that the pages specified are about to be swapped for different pages. Direct memory access activities involving the specified pages should be suspended until Service_PagesSafe has been received indicating the pages are safe.

You must not claim this service call.

This service call is only issued from RISC OS 3.5 onwards.


Service_PagesSafe
(Service Call &8F)

Pages specified have been swapped for different pages

On entry

R1 = &8F (reason code)
R2 = number of entries in each page block
R3 = pointer to page block before move
R4 = pointer to page block after move

On exit

All registers preserved

Use

This service call informs recipients that the pages specified have been swapped for different pages and what those different pages are.

The logical addresses in both page blocks will match. The 'before' page block will contain the physical page numbers and physical addresses of the pages which were swapped, and the 'after' block the page numbers and physical addresses of the different pages which replaced them.

You must not claim this service call.

This service call is only issued from RISC OS 3.5 onwards.


Service_DynamicAreaCreate
(Service Call &90)

Dynamic area has just been successfully created

On entry

R1 = &90 (reason code)
R2 = area number of dynamic area just created

On exit

All registers preserved

Use

This service call is issued just after the successful creation of a dynamic area.

This service call keeps the rest of the system informed about changes to the dynamic areas. It is used by the Task Manager, although other modules could make use of it.

You must not claim this service call.

This service call is only issued from RISC OS 3.5 onwards.


Service_DynamicAreaRemove
(Service Call &91)

Dynamic area is about to be removed

On entry

R1 = &91 (reason code)
R2 = area number of dynamic area about to be removed

On exit

All registers preserved

Use

This service call is issued just before the removal of a dynamic area, after the area has been successfully reduced to zero size, but before it has been removed completely.

This service call keeps the rest of the system informed about changes to the dynamic areas. It is used by the Task Manager, although other modules could make use of it.

You must not claim this service call.

This service call is only issued from RISC OS 3.5 onwards.


Service_DynamicAreaRenumber
(Service Call &92)

Dynamic area is being renumbered

On entry

R1 = &92 (reason code)
R2 = old area number
R3 = new area number

On exit

All registers preserved

Use

This service call is issued when a dynamic area is being renumbered.

This service call keeps the rest of the system informed about changes to the dynamic areas. It is used by the Task Manager, although other modules could make use of it.

You must not claim this service call.

This service call is only issued from RISC OS 3.5 onwards.

SWI calls


OS_DynamicArea
(SWI &66)

Performs operations on dynamic areas

On entry

R0 = reason code
Other registers depend upon the reason code

On exit

R0 preserved
Other registers depend upon the reason code

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This SWI provides a number of calls to perform operations on dynamic areas.

The particular action of OS_DynamicArea is given by the reason code in R0 as follows:

R0 Action Page
0 Creates a new dynamic area OS_DynamicArea 0
1 Removes a previously created dynamic area OS_DynamicArea 1
2 Returns information on a dynamic area OS_DynamicArea 2
3 Enumerates dynamic areas OS_DynamicArea 3
4 Renumbers dynamic areas OS_DynamicArea 4

This call is only available from RISC OS 3.5 onwards.

Related SWIs

OS_ChangeDynamicArea

Related vectors

None


OS_DynamicArea 0
(SWI &66)

Creates a new dynamic area

On entry

R0 = 0 (reason code)
R1 = -1 (or new area number not in range 128 - 255; this is reserved for Acorn use)
R2 = initial size of area, in bytes
R3 = -1 (or base logical address of area; this is reserved for Acorn use)
R4 = area flags (see below)
R5 = maximum size of area, in bytes (-1 => total RAM size of the machine)
R6 =pointer to dynamic area handler routine, or 0 if no routine
R7 = pointer to workspace, passed in R12 on entry to dynamic area handler routine; or -1 for RISC OS to instead pass base address of area; or 0 if R6 = 0
R8 = pointer to null terminated string describing dynamic area (e.g. 'Font cache')

On exit

R0 preserved
R1 = allocated area number
R2 preserved
R3 = specified or allocated base address of area
R4 preserved
R5 = specified or allocated maximum size of area
R6 - R8 preserved

Use

This call creates a new dynamic area.

The area is created initially with size zero (no pages assigned to it), and is then grown to the size specified in R2, which involves calling the area handler (if any) pointed to by R6. The area's maximum size is set to the lesser of the amount given in R5 on entry and the total RAM size of the machine; or to the total RAM size if R5 was -1 on entry.

RISC OS allocates a free area of logical address space which is big enough for the dynamic area's maximum size. The base logical address is the lowest logical address used by that area. The area grows by adding pages at the high address end.

RISC OS allocates an area number itself, which is greater than or equal to 256. This means that a call to OS_ReadDynamicArea will always return the maximum area size in R2 for these areas.

The area flags passed in R4 are as follows:

Bit(s) Meaning
0 - 3 access privileges to be given to each page in the area (same format as for OS_Read/SetMemMapEntries)
4 0 => area is bufferable
1 => area is not bufferable
5 0 => area is cacheable
1 => area is not cacheable
6 0 => area is singly mapped
1 => area is doubly mapped (reserved for Acorn use)
7 0 => area size may be dragged by the user in Task Manager window (has red bar)
1 => area size may not be dragged by the user in Task Manager window (has green bar)
8 0 => area does not require specific physical pages (ie R1 is undefined on entry to the PreGrow and PostGrow handlers)
1 => area may require specific physical pages (ie R1 points at a page block on entry to the PreGrow and PostGrow handlers)
9 - 31 reserved (must be zero)

The description string passed in R8 is used by the TaskManager in its display.

Once the area has been created, Service_DynamicAreaCreate is issued to inform the rest of the system about this change.

If the create dynamic area call returns an error for any reason, it may be assumed that the new area has not been created.

Notes for application writers

Applications should create only singly-mapped areas, and request that RISC OS allocate area numbers and logical addresses. This will prevent clashes of area numbers or addresses. For details of other usage, which has been provided largely for internal backwards compatibility, see the section entitled System use below.

Dynamic area handler routine

On entry, R6 points to the area handler routine which gets called with various reason codes when an area is grown or shrunk, and R7 specifies the workspace pointer that is passed to it in R12. If zero is passed in R6, then no routine will be called, and any shrink or grow will be allowed.

Details of the entry and exit conditions for this routine are given in the Dynamic area handler routinessection.

Errors

An error will be returned if:

  • the given area number clashes with an existing area.
  • the given base address is not on a memory page boundary.
  • the logical address space occupied by the area at maximum size would intersect with any other area at maximum size.
  • there is not enough contiguous logical address space to create the area.
  • there is not enough memory in the free pool to allocate level 2 page tables to cover the area at maximum size.
  • there is not enough memory to grow the area to the initial size requested.
System use

The following facilities are intended for internal system use only:

  • The ability to create areas with specific area numbers.
  • The ability to create areas at specific logical addresses.

    On entry, R3 holds the base address of the area, which must be aligned on a memory page boundary (to read the page size use OS_ReadMemMapInfo). With this usage, RISC OS does not allocate and area of logical address spage for the dynamic area.

  • The ability to create doubly-mapped areas.

    For doubly mapped areas the base logical address is the (fixed) boundary between the two mappings: the first mapping ends at R3-1, and the second starts at R3. When one of these areas grows, the pages in the first one copy move down to accomodate the new pages at the end, and the second copy simply grows at the end.


OS_DynamicArea 1
(SWI &66)

Removes a previously created dynamic area

On entry

R0 = 1 (reason code)
R1 = area number

On exit

All registers preserved

Use

This call removes a previously created dynamic area.

Before the area is removed, RISC OS attempts to shrink it to zero size. This is done using OS_ChangeDynamicArea. If OS_ChangeDynamicArea returns an error, then the area will be grown back to its original size using OS_ChangeDynamicArea, and this call will return with an error. If OS_ChangeDynamicArea successfully reduced the area to zero size, then it will be removed.

Once the area has been removed Service_DynamicAreaRemove is issued to inform the rest of the system about this change.

An error is returned if the area was not removed for any reason.


OS_DynamicArea 2
(SWI &66)

Returns information on a dynamic area

On entry

R0 = 2 (reason code)
R1 = area number

On exit

R0, R1 preserved
R2 = current size of area, in bytes
R3 = base logical address of area
R4 = area flags
R5 = maximum size of area, in bytes
R6 = pointer to dynamic area handler routines, or 0 if no routine
R7 = pointer to workspace, passed in R12 on entry to dynamic area handler routine
R8 = pointer to null terminated string describing dynamic area (e.g. 'Font cache')

Use

This call returns information on a dynamic area.

For doubly-mapped areas, R3 on exit from this call returns the address of the boundary between the first and second copies of the area, whereas OS_ReadDynamicArea returns the start address of the first copy (for backwards compatibility).


OS_DynamicArea 3
(SWI &66)

Enumerates dynamic areas

On entry

R0 = 3 (reason code)
R1 = -1 to start enumeration, or area number

On exit

R1 = next area number, or -1 if no further areas

Use

This call enumerates dynamic areas.

This allows an application to find out what dynamic areas are defined. -1 is passed on entry to start the enumeration; the call is then repeated until -1 is returned on exit, which indicates that the enumeration has finished.


OS_DynamicArea 4
(SWI &66)

Renumbers dynamic areas

On entry

R0 = 4 (reason code)
R1 = old area number
R2 = new area number

On exit

R0 - R2 preserved

Use

This call renumbers dynamic areas, and is intended for system use only.

Once the area has been renumbered Service_DynamicAreaRenumber is issued to inform the rest of the system about this change.

An error is returned if the area specified by the old area number does not exist, or if the new number clashes with an existing area.


OS_Memory
(SWI &68)

Performs miscellaneous operations for memory management

On entry

R0 = reason code (bits 0 - 7) and flags (bits 8 - 31, reason code specific)
Other registers depend upon the reason code

On exit

R0 preserved
Other registers depend upon the reason code

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This SWI performs miscellaneous operations for memory management.

The particular action of OS_Memory is given by the reason code in bits 0 - 7 of R0 as follows:

R0 Action page
0 General page block operations OS_Memory 0
1 - 5 Reserved for system use OS_Memory 1 - 5
6 Reads the size of the physical memory arrangement table OS_Memory 6
7 Reads the physical memory arrangement table OS_Memory 7
8 Reads the amount of a specified sort of memory available in the computer OS_Memory 8
9 Reads controller presence and base address OS_Memory 9

This call is only available from RISC OS 3.5 onwards.

Related SWIs

None

Related vectors

None


OS_Memory 0
(SWI &68)

General page block operations

On entry

R0 = reason code and flags:

Bits Meaning
0 - 7 0 (reason code)
8 physical page number provided when set
9 logical address provided when set
10 physical address provided when set
11 physical page number will be filled in when set (if bit 8 also clear)
12 logical address will be filled in when set (if bit 9 also clear)
13 physical address will be filled in when set (if bit 10 also clear)
14 - 15 cacheability control:
0 => no change
1 => no change
2 => disable cacheing on all specified pages
3 => enable cacheing on all specified pages
16 - 31 reserved (must be clear)
R1 = pointer to page block
R2 = number of entries in page block
On exit

R0 - R2 preserved

Use

This call converts between the different memory spaces used to specify addresses in a page block: i.e. logical address, physical address, and physical page number. It can also alter the cacheability of pages. The addresses must be in RAM, but need not be page-aligned. You can do address conversions and control the cacheability on a per-page basis. You need not do any conversion when changing cacheability (i.e. bits 11 - 13 may be clear).

The page block is scanned and the specified operations applied to it. If any page is made physically uncacheable, then the cache will be flushed before the SWI exits. If any page cannot be converted or is non-existent then an error will be returned and the cacheability unaffected.

Cacheability is accumulated for each page. For example, if there are five clients which need cacheing turned off on a page, then each of them must turn cacheing back on individually for that page actually to become cached again.

Where an ambiguity may occur, for example in doubly-mapped areas such as the screen, one of the possible results will be chosen and filled in.


OS_Memory 1 - 5
(SWI &68)

These reason codes are for system use only; you must not use them in your own code.


OS_Memory 6
(SWI &68)

Reads the size of the physical memory arrangement table

On entry

R0 = 6 (reason code); all flags are reserved, so bits 8 - 31 must be clear

On exit

R0 preserved
R1 = table size (in bytes)
R2 = page size (in bytes)

Use

This call reads the size of the physical memory arrangement table, as returned by OS_Memory 7.


OS_Memory 7
(SWI &68)

Reads the physical memory arrangement table

On entry

R0 = 7 (reason code); all flags are reserved, so bits 8 - 31 must be clear
R1 = pointer to table to be filled in

On exit

R0, R1 preserved

Use

This call reads the physical memory arrangement table into the block of memory pointed to by R1. (You can find the required size of the block by calling OS_Memory 6.)

Each page of physical memory space has one entry in the table. Due to the large number of pages the table is packed down to only 4 bits per page. In each byte of the table the low order 4 bits correspond to the page before the high order 4 bits, i.e. the table is little-endian. This is the meaning of a nibble in the table:

Bit Meaning
0 - 2 type of memory:
0 not present
1 DRAM
2 VRAM
3 ROM
4 I/O
5 - 7 undefined
3 0 => page available for allocation
1 => page not available for allocation

The page availability is based on whether it is RAM, and whether it has already been allocated in such a way that it can't be replaced with a different RAM page eg the OS's page tables or screen memory.

If an area has particular requirements on the physical addresses used by it (eg if it needs contiguous physical memory for its area) we recommend that you issue this call inside the area's PreGrow handler, and then choose which pages to ask for on the basis of this information. This is preferable to issuing the call before you create the area, because the page availability may change during the process of creating the area.


OS_Memory 8
(SWI &68)

Reads the amount of a specified sort of memory available in the computer

On entry

R0 = reason code and flags:

Bits Meaning
0 - 7 8 (reason code)
8 - 11 type of memory:
1 => DRAM
2 => VRAM
3 => ROM
4 => I/O
12 - 31 reserved (must be clear)

On exit

R0 preserved
R1 = number of pages of specified sort of memory
R2 = page size (in bytes)

Use

This call reads the amount of a specified sort of memory available in the computer. For I/O memory, all I/O memory is included: ie I/O space, VIDC space, and EASI space.


OS_Memory 9
(SWI &68)

Reads controller presence and base address

On entry

R0 = 9 (reason code); all flags are reserved, so bits 8 - 31 must be clear
R1 = controller ID:

Bit Meaning
0 - 7 controller sequence number
8 - 31 controller type:
0 => EASI card access speed control (for internal use only)
1 => EASI space (for internal use only)
2 => VIDC1
3 => VIDC20

On exit

R0 preserved
R1 = controller base address, or 0 if not present.

Use

This call checks for the presence of a given controller, and returns its base address if it is fitted. Controllers are identified by type and sequence number so that a machine could be constructed with, say, more than one IDE controller in it.

For EASI space this call gives the base address of expansion card n, where n is the sequence number given. This reason code is provided for internal use only and is documented here for completeness' sake. In particular you must use the Expansion Card Manager to read this information and to control your expansion card's EASI space access speed.


OS_MMUControl
(SWI &6B)

Modifies the ARM MMU control register

On entry

R0 = reason code and flags (must be zero)
R1 = XOR mask
R2 = AND mask

On exit

R1 = old value of control register
R2 = new value of control register

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call modifies the ARM MMU control register. The new value of the register is:

((old value AND R2) XOR R1)

The old value of the register is returned in R1, and the new value in R2. If the call results in the C (Cache enable) bit being changed, the cache is flushed.

This call is intended for internal system use only. Users wishing to enable or disable the cache should use the *Cache command instead.

This call is only available from RISC OS 3.5 onwards.

Related SWIs

None

Related vectors

None

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015