h6. [[OS SWI Calls]] h6(. » [[OS_Memory]] h6((. » [[OS_Memory 0]] h6(((. » Flags h2. Flags |_<^{width:4em}. Bits |_<^. Meaning when set | |<^. 0-7 |<^. 0 (reason code) | |<^. 8 |<^. Physical page number provided | |<^. 9 |<^. Logical address provided | |<^. 10 |<^. Physical address provided | |<^. 11 |<^. Return physical page number (if bit 8 clear) | |<^. 12 |<^. Return logical address (if bit 9 clear) | |<^. 13 |<^. Return physical address (if bit 10 clear) | |/4<^. 14-15 |<^. Cacheability control: [1] | |<^. 0,1 = No change| |<^. 2 = Disable cacheing on all specified pages | |<^. 3 = Enable cacheing on all specified pages | |<^. 16-31 |<^. Reserved, must be clear | h4. Notes These flags are specific to OS_Memory 0. fn1. *Cacheability control* As of RISC OS 5.25, using OS_Memory 0 to alter the cacheability of "shared" pages of memory is deprecated. In this context, "shared" is being used to refer to any page which your software does not have exclusive access to. E.g. if you allocate a block of memory from the RMA, there's a good chance that the pages at the start and end of that block will contain other blocks which have been allocated by other programs. Therefore those pages are "shared", and there is no way for you or the OS to predict how or when the other programs will access those other allocations (they could be accessed from foreground code after OS_Memory has disabled caching, or they could be accessed from IRQ or FIQ handlers during the OS_Memory operation). There are several reasons for this deprecation: * Most ARM chips ignore "unexpected" cache hits. When a page is made uncacheable, the OS first updates the attributes in the page table entry, then it flushes the cached page table entry from the CPU's TLB, and then it cleans and invalidates the cache lines for that page. After the first step, any data/instruction access which the CPU makes to the page may bypass the cache, ignoring any dirty cache lines which have yet to be written out to memory. This will result in that code reading incorrect values from the page (or writing a value which will later get overwritten by a dirty cache line). The OS contains workarounds for this behaviour, but these workarounds involve disabling IRQs and FIQs, which may have an impact on timing-sensitive device drivers. ** Note: These workarounds were only introduced in RISC OS 5.24. Software running on earlier OS versions may therefore encounter problems if OS_Memory 0 is used to disable caching for a page which is in use by an interrupt handler (specifically, the issue was seen on ARMv5 and newer CPUs) * The load/store exclusive instructions introduced in ARMv6 typically only operate on cacheable memory. Attempting to use them on uncacheable memory will result in an abort being raised by the CPU. Since the correct operation of these instructions is important to the OS and its apps, it's dangerous for software to use OS_Memory 0 to make shared pages of memory uncacheable, because the caller of OS_Memory 0 can't predict whether any software is going to be performing exclusive load/store operations to the shared regions of the pages. * On SMP versions of the OS, extra effort will be needed by the OS to make sure that the other cores aren't using the pages while their cacheability is being modified (due to the unexpected cache hit behaviour). As well as the extra complexity this will introduce to the call, it is also likely to result in performance degradation as the other cores will have to have their execution paused for the duration of the operation. The primary user of the "disable caching" / "enable caching" functionality was DMA drivers, for which [[OS_Memory 19]] has been introduced to act as a replacement. h4. See also * [[OS_Memory]] * [[OS_Memory 0]] * [[OS_Memory Page Blocks]] [link3]OS_Memory%200%20Flags [link4]OS_Memory%20Page%20Blocks