~funderscore blog cgit wiki get in touch
aboutsummaryrefslogtreecommitdiff
blob: 26ba9e530f1389591a043d0f1fad2d207ac06192 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
This document describes the generic device tree binding for IOMMUs and their
master(s).


IOMMU device node:
==================

An IOMMU can provide the following services:

* Remap address space to allow devices to access physical memory ranges that
  they otherwise wouldn't be capable of accessing.

  Example: 32-bit DMA to 64-bit physical addresses

* Implement scatter-gather at page level granularity so that the device does
  not have to.

* Provide system protection against "rogue" DMA by forcing all accesses to go
  through the IOMMU and faulting when encountering accesses to unmapped
  address regions.

* Provide address space isolation between multiple contexts.

  Example: Virtualization

Device nodes compatible with this binding represent hardware with some of the
above capabilities.

IOMMUs can be single-master or multiple-master. Single-master IOMMU devices
typically have a fixed association to the master device, whereas multiple-
master IOMMU devices can translate accesses from more than one master.

The device tree node of the IOMMU device's parent bus must contain a valid
"dma-ranges" property that describes how the physical address space of the
IOMMU maps to memory. An empty "dma-ranges" property means that there is a
1:1 mapping from IOMMU to memory.

Required properties:
--------------------
- #iommu-cells: The number of cells in an IOMMU specifier needed to encode an
  address.

The meaning of the IOMMU specifier is defined by the device tree binding of
the specific IOMMU. Below are a few examples of typical use-cases:

- #iommu-cells = <0>: Single master IOMMU devices are not configurable and
  therefore no additional information needs to be encoded in the specifier.
  This may also apply to multiple master IOMMU devices that do not allow the
  association of masters to be configured. Note that an IOMMU can by design
  be multi-master yet only expose a single master in a given configuration.
  In such cases the number of cells will usually be 1 as in the next case.
- #iommu-cells = <1>: Multiple master IOMMU devices may need to be configured
  in order to enable translation for a given master. In such cases the single
  address cell corresponds to the master device's ID. In some cases more than
  one cell can be required to represent a single master ID.
- #iommu-cells = <4>: Some IOMMU devices allow the DMA window for masters to
  be configured. The first cell of the address in this may contain the master
  device's ID for example, while the second cell could contain the start of
  the DMA window for the given device. The length of the DMA window is given
  by the third and fourth cells.

Note that these are merely examples and real-world use-cases may use different
definitions to represent their individual needs. Always refer to the specific
IOMMU binding for the exact meaning of the cells that make up the specifier.


IOMMU master node:
==================

Devices that access memory through an IOMMU are called masters. A device can
have multiple master interfaces (to one or more IOMMU devices).

Required properties:
--------------------
- iommus: A list of phandle and IOMMU specifier pairs that describe the IOMMU
  master interfaces of the device. One entry in the list describes one master
  interface of the device.

When an "iommus" property is specified in a device tree node, the IOMMU will
be used for address translation. If a "dma-ranges" property exists in the
device's parent node it will be ignored. An exception to this rule is if the
referenced IOMMU is disabled, in which case the "dma-ranges" property of the
parent shall take effect. Note that merely disabling a device tree node does
not guarantee that the IOMMU is really disabled since the hardware may not
have a means to turn off translation. But it is invalid in such cases to
disable the IOMMU's device tree node in the first place because it would
prevent any driver from properly setting up the translations.

Optional properties:
--------------------
- pasid-num-bits: Some masters support multiple address spaces for DMA, by
  tagging DMA transactions with an address space identifier. By default,
  this is 0, which means that the device only has one address space.

- dma-can-stall: When present, the master can wait for a transaction to
  complete for an indefinite amount of time. Upon translation fault some
  IOMMUs, instead of aborting the translation immediately, may first
  notify the driver and keep the transaction in flight. This allows the OS
  to inspect the fault and, for example, make physical pages resident
  before updating the mappings and completing the transaction. Such IOMMU
  accepts a limited number of simultaneous stalled transactions before
  having to either put back-pressure on the master, or abort new faulting
  transactions.

  Firmware has to opt-in stalling, because most buses and masters don't
  support it. In particular it isn't compatible with PCI, where
  transactions have to complete before a time limit. More generally it
  won't work in systems and masters that haven't been designed for
  stalling. For example the OS, in order to handle a stalled transaction,
  may attempt to retrieve pages from secondary storage in a stalled
  domain, leading to a deadlock.


Notes:
======

One possible extension to the above is to use an "iommus" property along with
a "dma-ranges" property in a bus device node (such as PCI host bridges). This
can be useful to describe how children on the bus relate to the IOMMU if they
are not explicitly listed in the device tree (e.g. PCI devices). However, the
requirements of that use-case haven't been fully determined yet. Implementing
this is therefore not recommended without further discussion and extension of
this binding.


Examples:
=========

Single-master IOMMU:
--------------------

	iommu {
		#iommu-cells = <0>;
	};

	master {
		iommus = <&{/iommu}>;
	};

Multiple-master IOMMU with fixed associations:
----------------------------------------------

	/* multiple-master IOMMU */
	iommu {
		/*
		 * Masters are statically associated with this IOMMU and share
		 * the same address translations because the IOMMU does not
		 * have sufficient information to distinguish between masters.
		 *
		 * Consequently address translation is always on or off for
		 * all masters at any given point in time.
		 */
		#iommu-cells = <0>;
	};

	/* static association with IOMMU */
	master@1 {
		reg = <1>;
		iommus = <&{/iommu}>;
	};

	/* static association with IOMMU */
	master@2 {
		reg = <2>;
		iommus = <&{/iommu}>;
	};

Multiple-master IOMMU:
----------------------

	iommu {
		/* the specifier represents the ID of the master */
		#iommu-cells = <1>;
	};

	master@1 {
		/* device has master ID 42 in the IOMMU */
		iommus = <&{/iommu} 42>;
	};

	master@2 {
		/* device has master IDs 23 and 24 in the IOMMU */
		iommus = <&{/iommu} 23>, <&{/iommu} 24>;
	};

Multiple-master IOMMU with configurable DMA window:
---------------------------------------------------

	/ {
		iommu {
			/*
			 * One cell for the master ID and one cell for the
			 * address of the DMA window. The length of the DMA
			 * window is encoded in two cells.
			 *
			 * The DMA window is the range addressable by the
			 * master (i.e. the I/O virtual address space).
			 */
			#iommu-cells = <4>;
		};

		master {
			/* master ID 42, 4 GiB DMA window starting at 0 */
			iommus = <&{/iommu}  42  0  0x1 0x0>;
		};
	};