| *** Reserved memory regions *** |
| |
| Reserved memory is specified as a node under the /reserved-memory node. |
| The operating system shall exclude reserved memory from normal usage |
| one can create child nodes describing particular reserved (excluded from |
| normal use) memory regions. Such memory regions are usually designed for |
| the special usage by various device drivers. |
| |
| Parameters for each memory region can be encoded into the device tree |
| with the following nodes: |
| |
| /reserved-memory node |
| --------------------- |
| #address-cells, #size-cells (required) - standard definition |
| - Should use the same values as the root node |
| ranges (required) - standard definition |
| - Should be empty |
| |
| /reserved-memory/ child nodes |
| ----------------------------- |
| Each child of the reserved-memory node specifies one or more regions of |
| reserved memory. Each child node may either use a 'reg' property to |
| specify a specific range of reserved memory, or a 'size' property with |
| optional constraints to request a dynamically allocated block of memory. |
| |
| Following the generic-names recommended practice, node names should |
| reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit |
| address (@<address>) should be appended to the name if the node is a |
| static allocation. |
| |
| Properties: |
| Requires either a) or b) below. |
| a) static allocation |
| reg (required) - standard definition |
| b) dynamic allocation |
| size (required) - length based on parent's #size-cells |
| - Size in bytes of memory to reserve. |
| alignment (optional) - length based on parent's #size-cells |
| - Address boundary for alignment of allocation. |
| alloc-ranges (optional) - prop-encoded-array (address, length pairs). |
| - Specifies regions of memory that are |
| acceptable to allocate from. |
| |
| If both reg and size are present, then the reg property takes precedence |
| and size is ignored. |
| |
| Additional properties: |
| compatible (optional) - standard definition |
| - may contain the following strings: |
| - shared-dma-pool: This indicates a region of memory meant to be |
| used as a shared pool of DMA buffers for a set of devices. It can |
| be used by an operating system to instantiate the necessary pool |
| management subsystem if necessary. |
| - restricted-dma-pool: This indicates a region of memory meant to be |
| used as a pool of restricted DMA buffers for a set of devices. The |
| memory region would be the only region accessible to those devices. |
| When using this, the no-map and reusable properties must not be set, |
| so the operating system can create a virtual mapping that will be used |
| for synchronization. The main purpose for restricted DMA is to |
| mitigate the lack of DMA access control on systems without an IOMMU, |
| which could result in the DMA accessing the system memory at |
| unexpected times and/or unexpected addresses, possibly leading to data |
| leakage or corruption. The feature on its own provides a basic level |
| of protection against the DMA overwriting buffer contents at |
| unexpected times. However, to protect against general data leakage and |
| system memory corruption, the system needs to provide way to lock down |
| the memory access, e.g., MPU. Note that since coherent allocation |
| needs remapping, one must set up another device coherent pool by |
| shared-dma-pool and use dma_alloc_from_dev_coherent instead for atomic |
| coherent allocation. |
| - vendor specific string in the form <vendor>,[<device>-]<usage> |
| no-map (optional) - empty property |
| - Indicates the operating system must not create a virtual mapping |
| of the region as part of its standard mapping of system memory, |
| nor permit speculative access to it under any circumstances other |
| than under the control of the device driver using the region. |
| reusable (optional) - empty property |
| - The operating system can use the memory in this region with the |
| limitation that the device driver(s) owning the region need to be |
| able to reclaim it back. Typically that means that the operating |
| system can use that region to store volatile or cached data that |
| can be otherwise regenerated or migrated elsewhere. |
| |
| A node must not carry both the no-map and the reusable property as these are |
| logically contradictory. |
| |
| Linux implementation note: |
| - If a "linux,cma-default" property is present, then Linux will use the |
| region for the default pool of the contiguous memory allocator. |
| |
| - If a "linux,dma-default" property is present, then Linux will use the |
| region for the default pool of the consistent DMA allocator. |
| |
| Device node references to reserved memory |
| ----------------------------------------- |
| Regions in the /reserved-memory node may be referenced by other device |
| nodes by adding a memory-region property to the device node. |
| |
| memory-region (optional) - phandle, specifier pairs to children of /reserved-memory |
| memory-region-names (optional) - a list of names, one for each corresponding |
| entry in the memory-region property |
| |
| Example |
| ------- |
| This example defines 4 contiguous regions for Linux kernel: |
| one default of all device drivers (named linux,cma@72000000 and 64MiB in size), |
| one dedicated to the framebuffer device (named framebuffer@78000000, 8MiB), |
| one for multimedia processing (named multimedia-memory@77000000, 64MiB), and |
| one for restricted dma pool (named restricted_dma_reserved@0x50000000, 64MiB). |
| |
| / { |
| #address-cells = <1>; |
| #size-cells = <1>; |
| |
| memory { |
| reg = <0x40000000 0x40000000>; |
| }; |
| |
| reserved-memory { |
| #address-cells = <1>; |
| #size-cells = <1>; |
| ranges; |
| |
| /* global autoconfigured region for contiguous allocations */ |
| linux,cma { |
| compatible = "shared-dma-pool"; |
| reusable; |
| size = <0x4000000>; |
| alignment = <0x2000>; |
| linux,cma-default; |
| }; |
| |
| display_reserved: framebuffer@78000000 { |
| reg = <0x78000000 0x800000>; |
| }; |
| |
| multimedia_reserved: multimedia@77000000 { |
| compatible = "acme,multimedia-memory"; |
| reg = <0x77000000 0x4000000>; |
| }; |
| |
| restricted_dma_reserved: restricted_dma_reserved { |
| compatible = "restricted-dma-pool"; |
| reg = <0x50000000 0x4000000>; |
| }; |
| }; |
| |
| /* ... */ |
| |
| fb0: video@12300000 { |
| memory-region = <&display_reserved>; |
| /* ... */ |
| }; |
| |
| scaler: scaler@12500000 { |
| memory-region = <&multimedia_reserved>; |
| /* ... */ |
| }; |
| |
| codec: codec@12600000 { |
| memory-region = <&multimedia_reserved>; |
| /* ... */ |
| }; |
| |
| pcie_device: pcie_device@0,0 { |
| reg = <0x83010000 0x0 0x00000000 0x0 0x00100000 |
| 0x83010000 0x0 0x00100000 0x0 0x00100000>; |
| memory-region = <&restricted_dma_reserved>; |
| /* ... */ |
| }; |
| }; |