Showing changes from revision #4 to #5:
Added | Removed | Changed
Entry | |
---|---|
R0 | 19, and flags: |
Bit 8: Input function provides physical addresses (=1), else logical (=0) | |
Bit 9: DMA is writing to RAM | |
Bit 10: DMA is complete | |
Bits 12+: Reserved (set to 0) | |
R1 | R12 value to provide to called functions |
R2 | Initial R9 value to provide to input function |
R3 | Pointer to input function |
R4 | Initial R9 value to provide to output function |
R5 | Pointer to output function (if bit 10 of R0 clear) |
Exit | |
---|---|
R2 | Updated to match last value returned by input function |
R4 | Updated to match last value returned by output function |
- | All other registers preserved |
This call performs address translation and cache maintenance operations, as necessary to allow for DMA to be performed to/from cacheable memory. It’s intended to be used as a replacement for the OS_Memory 0/OS_Memory 64 “Enable/disable caching” feature, since there are many issues with that approach on modern systems.
As with OS_Memory 0, 0/64, OS_Memory 19 must be called twice perDMA operation: Once at the start of the operation (with bit 10 of R0 clear), and once at the end of the operation (with bit 10 set). The same list of input addresses ranges must be provided each time.
Key differences from OS_Memory 0 are as follows:
OS_Memory 19 operates under the following principles:
Under this strategy, it’s safe for programs (or other DMA controllers) to read from memory that is being accessed by a DMA read operation. Accessing cacheable memory which is being a DMA write operation is unsafe and should not be avoided (unless you’re careful to perform the necessary cache maintenance yourself).
Service_PagesUnsafeFor the 32 bit version of the call (flag bit 11 is zero), if a logical address maps to a physical address which is larger than 32 bits then that section of the transfer will be forced via a bounce buffer and the returned physical address will be undefined. To avoid this, the 64 bit version of the call should be used (flag bit 11 set). Although there’s no direct way of detecting if the 64 bit version of the call is supported, is issued by the OS whenever the physical page associated with a logical address is being “transparently” replaced with another physical page. This can occur as the result of the original physical page being requested by a OS_PlatformFeatures 0Dynamic Area PreGrow bit 21 can be used as an indicator that it’s supported / necessary. handler. Programs which perform DMA need to listen out for this service call so that they can pause DMA while the pages are being moved, and then resume DMA (using the new logical → physical mapping) once the page move is complete.
Because Service_PagesUnsafeOS_Memory 0 / does not perform any operations which might cause pages to be moved in this manner, programs which uses OS_Memory 0 only need to start paying attention to Service_PagesUnsafe once they’ve received the results from the OS. But for OS_Memory 19, results are returned to your code in a piecemeal fashion. If your input or output function performs operations which may trigger page movement (e.g. allocating pages from the Service_PagesUnsafe64RMA is issued by the OS whenever the physical page associated with a logical address is being “transparently” replaced with another physical page. This can occur as the result of the original physical page being requested by a ), extra care is needed in order to deal with Service_PagesUnsafe correctly.Dynamic Area PreGrow handler. Programs which perform DMA need to listen out for this service call so that they can pause DMA while the pages are being moved, and then resume DMA (using the new logical → physical mapping) once the page move is complete.
If Because a OS_Memory call 0/64 don’t perform any operations which might cause pages to be moved in this manner, programs which uses OS_Memory 0/64 only need to start paying attention to Service_PagesUnsafe/PagesUnsafe64 once they’ve received the results from the OS. But for OS_Memory 19, results are returned to your code in a piecemeal fashion. If your input or output function performs operations which may trigger page movement (e.g. allocating pages from theService_PagesUnsafeRMA ), occurs extra during care the is call needed to OS_Memory, and it affects the pages which are involved in the order OS_Memory to call: deal with Service_PagesUnsafe/PagesUnsafe64 correctly.
If a call to Service_PagesUnsafe / Service_PagesUnsafe64 occurs during the call to OS_Memory, and it affects the pages which are involved in the OS_Memory call:
If code is written to memory by a DMA operation then you must still call OS_SynchroniseCodeAreas afterwards to ensure the instruction cache has been invalidated.