172 lines
6.6 KiB
Plaintext
172 lines
6.6 KiB
Plaintext
|
*** 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>;
|
||
|
/* ... */
|
||
|
};
|
||
|
};
|