Showing changes from revision #0 to #1:
Added | Removed | Changed
Entry | |
---|---|
R0 | 22 (&16), and flag |
R1 | Physical address to map in (low 32 bits) |
R2 | Physical address to map in (high 32 bits) |
Exit | |
---|---|
R0 | Preserved |
R1 | Preserved |
R2 | Logical address corresponding to R1,R2 |
R3 | Reference key (required when releasing) |
The purpose of this call is to temporarily map in one megabyte of IO memory at run-time. The megabyte that gets mapped in will be megabyte-aligned in both the logical and physical address spaces; i.e. by accessing (R2 AND &FFF00000) you will be accessing physical address ((R2<<32) + (R1 AND &FFF00000)). Although the base of the mapping is on a megabyte boundary, the value returned in R2 will have had an offset applied to it so that it corresponds to the exact address requested in R1,R2.
Because of the megabyte alignment of the mapping, if you are reading multiple bytes from R2 you must be careful not to cross a megabyte boundary.
All calls to OS_Memory 14 and OS_Memory 22 will manipulate a single shared region of the logical address map. Therefore, only one region can be mapped in at once – it is impossible to use this call to concurrently access regions of physical memory which lie in different megabytes.
This also means that this call must not be used for any long-life mappings – i.e. it is not acceptable to map in a region during a module’s initialisation and continue to access that region throughout the life of the module. If two such modules using the above method were left running at the same time then they would inadvertently access each other’s memory, leading to crashes, data corruption, or other improper behaviour. Instead, you must map in the region each time your code gains control of the system.
Because there is only one single megabyte region available, it is also vitally important to use OS_Memory 15 to restore the state of the region once you have finished using it. This makes sure that interrupt handlers, callbacks, etc. don’t corrupt the mapping of any foreground process.
If you want to access multiple different regions in sequence, then it is only necessary to call OS_Memory 15 once, with the value of R3 that was returned to you the first time you called OS_Memory 14/22. This will restore the region to the state it was before your first call.
Depending on the OS version and host hardware, the size of the mapping created may be more than 1MB. However this is an implementation detail and your code should not rely on that behaviour.
This call was introduced in RISC OS 5.27, to improve upon the existing OS_Memory 14 call (which can only deal with 32-bit physical addresses). For compatibility with older OS versions, it’s recommended to use OS_Memory 14 whenever 32-bit physical addresses are sufficient.