2. The Devicetree¶
2.1. Overview¶
DTSpec specifies a construct called a devicetree to describe system hardware. A boot program loads a devicetree into a client program’s memory and passes a pointer to the devicetree to the client.
This chapter describes the logical structure of the devicetree and specifies a base set of properties for use in describing device nodes. Chapter 3 specifies certain device nodes required by a DTSpec compliant devicetree. Chapter 6 describes the DTSpec defined device bindings— the requirements for representing certain device types classes of devices. Chapter 8 describes the in-memory encoding of the devicetree.
A devicetree is a tree data structure with nodes that describe the devices in a system. Each node has property/value pairs that describe the characteristics of the device being represented. Each node has exactly one parent except for the root node, which has no parent.
An DTSpec-compliant devicetree describes device information in a system that cannot necessarily be dynamically detected by a client program. For example, the architecture of PCI enables a client to probe and detect attached devices, and thus devicetree nodes describing PCI devices might not be required. However, a device node is required to describe a PCI host bridge device in the system if it cannot be detected by probing.
Example
Fig. 2.1 shows an example representation of a simple devicetree that is nearly complete enough to boot a simple operating system, with the platform type, CPU, and memory described. Device nodes are shown with properties and values shown beside the node.
2.2. Devicetree Structure and Conventions¶
2.2.1. Node Names¶
2.2.1.1. Node Name Requirements¶
Each node in the devicetree is named according to the following convention:
node-name@unit-address
The node-name component specifies the name of the node. It shall be 1 to 31 characters in length and consist solely of characters from the set of characters in Table 2.1.
Character | Description |
---|---|
0-9 |
digit |
a-z |
lowercase letter |
A-Z |
uppercase letter |
, |
comma |
. |
period |
_ |
underscore |
+ |
plus sign |
- |
dash |
The node-name shall start with a lower or uppercase character and should describe the general class of device.
The unit-address component of the name is specific to the bus type on which the node sits. It consists of one or more ASCII characters from the set of characters in Table 2.1. The unit-address must match the first address specified in the reg property of the node. If the node has no reg property, the @unit-address must be omitted and the node-name alone differentiates the node from other nodes at the same level in the tree. The binding for a particular bus may specify additional, more specific requirements for the format of reg and the unit-address.
The root node does not have a node-name or unit-address. It is identified by a forward slash (/).
In Fig. 2.2:
- The nodes with the name cpu are distinguished by their unit-address values of 0 and 1.
- The nodes with the name Ethernet are distinguished by their unit-address values of FE001000 and FE002000.
2.2.2. Generic Names Recommendation¶
The name of a node should be somewhat generic, reflecting the function of the device and not its precise programming model. If appropriate, the name should be one of the following choices:
|
|
|
2.2.3. Path Names¶
A node in the devicetree can be uniquely identified by specifying the full path from the root node, through all descendant nodes, to the desired node.
The convention for specifying a device path is:
/node-name-1/node-name-2/node-name-N
For example, in Fig. 2.2, the device path to cpu #1 would be:
/cpus/cpu@1
The path to the root node is /.
A unit address may be omitted if the full path to the node is unambiguous.
If a client program encounters an ambiguous path, its behavior is undefined.
2.2.4. Properties¶
Each node in the devicetree has properties that describe the characteristics of the node. Properties consist of a name and a value.
2.2.4.1. Property Names¶
Property names are strings of 1 to 31 characters from the characters show in Table 2.2
Character | Description |
---|---|
0-9 |
digit |
a-z |
lowercase letter |
A-Z |
uppercase letter |
, |
comma |
. |
period |
_ |
underscore |
+ |
plus sign |
? |
question mark |
# |
hash |
Nonstandard property names should specify a unique string prefix, such as a stock ticker symbol, identifying the name of the company or organization that defined the property. Examples:
fsl,channel-fifo-len
ibm,ppc-interrupt-server#s
linux,network-index
2.2.4.2. Property Values¶
A property value is an array of zero or more bytes that contain information associated with the property.
Properties might have an empty value if conveying true-false information. In this case, the presence or absence of the property is sufficiently descriptive.
Table 2.3 describes the set of basic value types defined by the DTSpec.
Value | Description |
---|---|
<empty> |
Value is empty. Used for conveying true-false information, when the presence of absence of the property itself is sufficiently descriptive. |
<u32> |
A 32-bit integer in big-endian format. Example: the 32-bit value 0x11223344 would be represented in memory as:
|
<u64> |
Represents a 64-bit integer in big-endian format. Consists of
two Example: the 64-bit value 0x1122334455667788 would be
represented as two cells as: The value would be represented in memory as:
|
<string> |
Strings are printable and null-terminated. Example: the string “hello” would be represented in memory as:
|
<prop-encoded-array> |
Format is specific to the property. See the property definition. |
<phandle> |
A <u32> value. A phandle value is a way to reference another
node in the devicetree. Any node that can be referenced defines
a phandle property with a unique <u32> value. That number
is used for the value of properties with a phandle value
type. |
<stringlist> |
A list of Example: The string list “hello”,”world” would be represented in memory as:
|
2.3. Standard Properties¶
DTSpec specifies a set of standard properties for device nodes. These properties are described in detail in this section. Device nodes defined by DTSpec (see Chapter 3) may specify additional requirements or constraints regarding the use of the standard properties. Chapter 4 describes the representation of specific devices may also specify additional requirements.
Note
All examples of devicetree nodes in this document use the DTS format for specifying nodes and properties.
2.3.1. compatible¶
Property name: compatible
Value type: <stringlist>
Description:
The compatible property value consists of one or more strings that define the specific programming model for the device. This list of strings should be used by a client program for device driver selection. The property value consists of a concatenated list of null terminated strings, from most specific to most general. They allow a device to express its compatibility with a family of similar devices, potentially allowing a single device driver to match against several devices.
The recommended format is
"manufacturer,model"
, wheremanufacturer
is a string describing the name of the manufacturer (such as a stock ticker symbol), andmodel
specifies the model number.
Example:
compatible = "fsl,mpc8641-uart", "ns16550";
In this example, an operating system would first try to locate a device driver that supported fsl,mpc8641-uart. If a driver was not found, it would then try to locate a driver that supported the more general ns16550 device type.
2.3.2. model¶
Property name: model
Value type: <stringlist>
Description:
The model property value is a
<string>
that specifies the manufacturer’s model number of the device.The recommended format is:
"manufacturer,model"
, wheremanufacturer
is a string describing the name of the manufacturer (such as a stock ticker symbol), and model specifies the model number.
Example:
model = "fsl,MPC8349EMITX";
2.3.3. phandle¶
Property name: phandle
Value type: <u32>
Description:
The phandle property specifies a numerical identifier for a node that is unique within the devicetree. The phandle property value is used by other nodes that need to refer to the node associated with the property.
Example:
See the following devicetree excerpt:
pic@10000000 { phandle = <1>; interrupt-controller; };A phandle value of 1 is defined. Another device node could reference the pic node with a phandle value of 1:
interrupt-parent = <1>;
Note
Older versions of devicetrees may be encountered that contain a
deprecated form of this property called linux,phandle
. For
compatibility, a client program might want to support linux,phandle
if a phandle
property is not present. The meaning and use of the two
properties is identical.
Note
Most devicetrees in DTS (see Appendix A) will not
contain explicit phandle properties. The DTC tool automatically inserts
the phandle
properties when the DTS is compiled into the binary DTB
format.
2.3.4. status¶
Property name: status
Value type: <string>
Description:
Thestatus
property indicates the operational status of a device. Valid values are listed and defined in Table 2.4.
Value | Description |
---|---|
"okay" |
Indicates the device is operational |
"disabled" |
Indicates that the device is not presently operational, but it might become operational in the future (for example, something is not plugged in, or switched off). Refer to the device binding for details on what disabled means for a given device. |
"fail" |
Indicates that the device is not operational. A serious error was detected in the device, and it is unlikely to become operational without repair. |
"fail-sss" |
Indicates that the device is not operational. A serious error was detected in the device and it is unlikely to become operational without repair. The sss portion of the value is specific to the device and indicates the error condition detected. |
2.3.5. #address-cells and #size-cells¶
Property name: #address-cells
, #size-cells
Value type: <u32>
Description:
The #address-cells and #size-cells properties may be used in any device node that has children in the devicetree hierarchy and describes how child device nodes should be addressed. The #address-cells property defines the number of
<u32>
cells used to encode the address field in a child node’s reg property. The #size-cells property defines the number of<u32>
cells used to encode the size field in a child node’s reg property.The #address-cells and #size-cells properties are not inherited from ancestors in the devicetree. They shall be explicitly defined.
An DTSpec-compliant boot program shall supply #address-cells and #size-cells on all nodes that have children.
If missing, a client program should assume a default value of 2 for #address-cells, and a value of 1 for #size-cells.
Example:
See the following devicetree excerpt:
soc { #address-cells = <1>; #size-cells = <1>; serial { compatible = "ns16550"; reg = <0x4600 0x100>; clock-frequency = <0>; interrupts = <0xA 0x8>; interrupt-parent = <&ipic>; }; };In this example, the #address-cells and #size-cells properties of the soc node are both set to 1. This setting specifies that one cell is required to represent an address and one cell is required to represent the size of nodes that are children of this node.
The serial device reg property necessarily follows this specification set in the parent (soc) node—the address is represented by a single cell (0x4600), and the size is represented by a single cell (0x100).
2.3.6. reg¶
Property name: reg
Property value: <prop-encoded-array>
encoded as an arbitraty number of (address, length) pairs.
Description:
The reg property describes the address of the device’s resources within the address space defined by its parent bus. Most commonly this means the offsets and lengths of memory-mapped IO register blocks, but may have a different meaning on some bus types. Addresses in the address space defined by root node are cpu real addresses.
The value is a <prop-encoded-array>, composed of an arbitrary number of pairs of address and length, <address length>. The number of <u32> cells required to specify the address and length are bus-specific and are specified by the #address-cells and #size-cells properties in the parent of the device node. If the parent node specifies a value of 0 for #size-cells, the length field in the value of reg shall be omitted.
Example:
Suppose a device within a system-on-a-chip had two blocks of registers, a 32-byte block at offset 0x3000 in the SOC and a 256-byte block at offset 0xFE00. The reg property would be encoded as follows (assuming #address-cells and #size-cells values of 1):
reg = <0x3000 0x20 0xFE00 0x100>;
2.3.7. virtual-reg¶
Property name: virtual-reg
Value type: <u32>
Description:
The virtual-reg property specifies an effective address that maps to the first physical address specified in the reg property of the device node. This property enables boot programs to provide client programs with virtual-to-physical mappings that have been set up.
2.3.8. ranges¶
Property name: ranges
Value type: <empty>
or <prop-encoded-array>
encoded as an arbitrary number of
(child-bus-address, parent-bus-address, length) triplets.
Description:
The ranges property provides a means of defining a mapping or translation between the address space of the bus (the child address space) and the address space of the bus node’s parent (the parent address space).
The format of the value of the ranges property is an arbitrary number of triplets of (child-bus-address, parent-bus-address, length)
- The child-bus-address is a physical address within the child bus’ address space. The number of cells to represent the address is bus dependent and can be determined from the #address-cells of this node (the node in which the ranges property appears).
- The parent-bus-address is a physical address within the parent bus’ address space. The number of cells to represent the parent address is bus dependent and can be determined from the #address-cells property of the node that defines the parent’s address space.
- The length specifies the size of the range in the child’s address space. The number of cells to represent the size can be determined from the #size-cells of this node (the node in which the ranges property appears).
If the property is defined with an
<empty>
value, it specifies that the parent and child address space is identical, and no address translation is required.If the property is not present in a bus node, it is assumed that no mapping exists between children of the node and the parent address space.
Address Translation Example:
soc { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0xe0000000 0x00100000>; serial { device_type = "serial"; compatible = "ns16550"; reg = <0x4600 0x100>; clock-frequency = <0>; interrupts = <0xA 0x8>; interrupt-parent = < &ipic >; }; };The
soc
node specifies a ranges property of<0x0 0xe0000000 0x00100000>;
This property value specifies that for an 1024KB range of address space, a child node addressed at physical 0x0 maps to a parent address of physical 0xe0000000. With this mapping, the
serial
device node can be addressed by a load or store at address 0xe0004600, an offset of 0x4600 (specified in reg) plus the 0xe0000000 mapping specified in ranges.
2.3.9. dma-ranges¶
Property name: dma-ranges
Value type: <empty>
or <prop-encoded-array>
encoded as an arbitrary number of
(child-bus-address, parent-bus-address, length) triplets.
Description:
The dma-ranges property is used to describe the direct memory access (DMA) structure of a memory-mapped bus whose devicetree parent can be accessed from DMA operations originating from the bus. It provides a means of defining a mapping or translation between the physical address space of the bus and the physical address space of the parent of the bus.
The format of the value of the dma-ranges property is an arbitrary number of triplets of (child-bus-address, parent-bus-address, length). Each triplet specified describes a contiguous DMA address range.
- The child-bus-address is a physical address within the child bus’ address space. The number of cells to represent the address depends on the bus and can be determined from the #address-cells of this node (the node in which the dma-ranges property appears).
- The parent-bus-address is a physical address within the parent bus’ address space. The number of cells to represent the parent address is bus dependent and can be determined from the #address-cells property of the node that defines the parent’s address space.
- The length specifies the size of the range in the child’s address space. The number of cells to represent the size can be determined from the #size-cells of this node (the node in which the dma-ranges property appears).
2.3.10. name (deprecated)¶
Property name: name
Value type: <string>
Description:
The name property is a string specifying the name of the node. This property is deprecated, and its use is not recommended. However, it might be used in older non-DTSpec-compliant devicetrees. Operating system should determine a node’s name based on the name component of the node name (see section 2.2.1).
2.3.11. device_type (deprecated)¶
Property name: device_type
Value type: <string>
Description:
The device_type property was used in IEEE 1275 to describe the device’s FCode programming model. Because DTSpec does not have FCode, new use of the property is deprecated, and it should be included only on cpu and memory nodes for compatibility with IEEE 1275–derived devicetrees.
2.4. Interrupts and Interrupt Mapping¶
DTSpec adopts the interrupt tree model of representing interrupts specified in Open Firmware Recommended Practice: Interrupt Mapping, Version 0.9 [b7]. Within the devicetree a logical interrupt tree exists that represents the hierarchy and routing of interrupts in the platform hardware. While generically referred to as an interrupt tree it is more technically a directed acyclic graph.
The physical wiring of an interrupt source to an interrupt controller is represented in the devicetree with the interrupt-parent property. Nodes that represent interrupt-generating devices contain an interrupt-parent property which has a phandle value that points to the device to which the device’s interrupts are routed, typically an interrupt controller. If an interrupt-generating device does not have an interrupt-parent property, its interrupt parent is assumed to be its devicetree parent.
Each interrupt generating device contains an interrupts property with
a value describing one or more interrupt sources for that device. Each
source is represented with information called an interrupt specifier.
The format and meaning of an interrupt specifier is interrupt domain
specific, i.e., it is dependent on properties on the node at the root of
its interrupt domain. The #interrupt-cells property is used by the
root of an interrupt domain to define the number of <u32>
values
needed to encode an interrupt specifier. For example, for an Open PIC
interrupt controller, an interrupt-specifer takes two 32-bit values and
consists of an interrupt number and level/sense information for the
interrupt.
An interrupt domain is the context in which an interrupt specifier is interpreted. The root of the domain is either (1) an interrupt controller or (2) an interrupt nexus.
- An interrupt controller is physical device and will need a driver to handle interrupts routed through it. It may also cascade into another interrupt domain. An interrupt controller is specified by the presence of an interrupt-controller property on that node in the devicetree.
- An interrupt nexus defines a translation between one interrupt domain and another. The translation is based on both domain-specific and bus-specific information. This translation between domains is performed with the interrupt-map property. For example, a PCI controller device node could be an interrupt nexus that defines a translation from the PCI interrupt namespace (INTA, INTB, etc.) to an interrupt controller with Interrupt Request (IRQ) numbers.
The root of the interrupt tree is determined when traversal of the interrupt tree reaches an interrupt controller node without an interrupts property and thus no explicit interrupt parent.
See Fig. 2.3 for an example of a graphical representation of a devicetree with interrupt parent relationships shown. It shows both the natural structure of the devicetree as well as where each node sits in the logical interrupt tree.
In the example shown in Fig. 2.3:
- The
open-pic
interrupt controller is the root of the interrupt tree. - The interrupt tree root has three children—devices that route their
interrupts directly to the
open-pic
- device1
- PCI host controller
- GPIO Controller
- Three interrupt domains exist; one rooted at the
open-pic
node, one at thePCI host bridge
node, and one at theGPIO Controller
node. - There are two nexus nodes; one at the
PCI host bridge
and one at theGPIO controller
.
2.4.1. Properties for Interrupt Generating Devices¶
2.4.1.1. interrupts¶
Property: interrupts
Value type: <prop-encoded-array>
encoded as arbitrary number of
interrupt specifiers
Description:
The interrupts property of a device node defines the interrupt or interrupts that are generated by the device. The value of the interrupts property consists of an arbitrary number of interrupt specifiers. The format of an interrupt specifier is defined by the binding of the interrupt domain root.
Example:
A common definition of an interrupt specifier in an open PIC–compatible interrupt domain consists of two cells; an interrupt number and level/sense information. See the following example, which defines a single interrupt specifier, with an interrupt number of 0xA and level/sense encoding of 8.
interrupts = <0xA 8>;
2.4.1.2. interrupt-parent¶
Property: interrupt-parent
Value type: <phandle>
Description:
Because the hierarchy of the nodes in the interrupt tree might not match the devicetree, the interrupt-parent property is available to make the definition of an interrupt parent explicit. The value is the phandle to the interrupt parent. If this property is missing from a device, its interrupt parent is assumed to be its devicetree parent.
2.4.2. Properties for Interrupt Controllers¶
2.4.2.1. #interrupt-cells¶
Property: #interrupt-cells
Value type: <u32>
Description:
The #interrupt-cells property defines the number of cells required to encode an interrupt specifier for an interrupt domain.
2.4.2.2. interrupt-controller¶
Property: interrupt-controller
Value type: <empty>
Description:
The presence of an interrupt-controller property defines a node as an interrupt controller node.
2.4.3. Interrupt Nexus Properties¶
An interrupt nexus node shall have an #interrupt-cells property.
2.4.3.1. interrupt-map¶
Property: interrupt-map
Value type: <prop-encoded-array>
encoded as an arbitrary number of
interrupt mapping entries.
Description:
An interrupt-map is a property on a nexus node that bridges one interrupt domain with a set of parent interrupt domains and specifies how interrupt specifiers in the child domain are mapped to their respective parent domains.
The interrupt map is a table where each row is a mapping entry consisting of five components: child unit address, child interrupt specifier, interrupt-parent, parent unit address, parent interrupt specifier.
- child unit address
- The unit address of the child node being mapped. The number of 32-bit cells required to specify this is described by the #address-cells property of the bus node on which the child is located.
- child interrupt specifier
- The interrupt specifier of the child node being mapped. The number of 32-bit cells required to specify this component is described by the #interrupt-cells property of this node—the nexus node containing the interrupt-map property.
- interrupt-parent
- A single <phandle> value that points to the interrupt parent to which the child domain is being mapped.
- parent unit address
- The unit address in the domain of the interrupt parent. The number of 32-bit cells required to specify this address is described by the #address-cells property of the node pointed to by the interrupt-parent field.
- parent interrupt specifier
- The interrupt specifier in the parent domain. The number of 32-bit cells required to specify this component is described by the #interrupt-cells property of this node—the nexus node containing the interrupt-map property.
Lookups are performed on the interrupt mapping table by matching a unit-address/interrupt specifier pair against the child components in the interrupt-map. Because some fields in the unit interrupt specifier may not be relevant, a mask is applied before the lookup is done. This mask is defined in the interrupt-map-mask property (see section 2.4.3.2).
Note
Both the child node and the interrupt parent node are required to have #address-cells and #interrupt-cells properties defined. If a unit address component is not required, #address-cells shall be explicitly defined to be zero.
2.4.3.2. interrupt-map-mask¶
Property: interrupt-map-mask
Value type: <prop-encoded-array>
encoded as a bit mask
Description:
An interrupt-map-mask property is specified for a nexus node in the interrupt tree. This property specifies a mask that is applied to the incoming unit interrupt specifier being looked up in the table specified in the interrupt-map property.
2.4.3.3. #interrupt-cells¶
Property: #interrupt-cells
Value type: <u32>
Description:
The #interrupt-cells property defines the number of cells required to encode an interrupt specifier for an interrupt domain.
2.4.4. Interrupt Mapping Example¶
The following shows the representation of a fragment of a devicetree with a PCI bus controller and a sample interrupt map for describing the interrupt routing for two PCI slots (IDSEL 0x11,0x12). The INTA, INTB, INTC, and INTD pins for slots 1 and 2 are wired to the Open PIC interrupt controller.
soc {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
open-pic {
clock-frequency = <0>;
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <2>;
};
pci {
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
interrupt-map-mask = <0xf800 0 0 7>;
interrupt-map = <
/* IDSEL 0x11 - PCI slot 1 */
0x8800 0 0 1 &open-pic 2 1 /* INTA */
0x8800 0 0 2 &open-pic 3 1 /* INTB */
0x8800 0 0 3 &open-pic 4 1 /* INTC */
0x8800 0 0 4 &open-pic 1 1 /* INTD */
/* IDSEL 0x12 - PCI slot 2 */
0x9000 0 0 1 &open-pic 3 1 /* INTA */
0x9000 0 0 2 &open-pic 4 1 /* INTB */
0x9000 0 0 3 &open-pic 1 1 /* INTC */
0x9000 0 0 4 &open-pic 2 1 /* INTD */
>;
};
};
One Open PIC interrupt controller is represented and is identified as an interrupt controller with an interrupt-controller property.
Each row in the interrupt-map table consists of five parts: a child unit address and interrupt specifier, which is mapped to an interrupt-parent node with a specified parent unit address and interrupt specifier.
For example, the first row of the interrupt-map table specifies the mapping for INTA of slot 1. The components of that row are shown here
child unit address:0x8800 0 0
child interrupt specifier:1
interrupt parent:&open-pic
parent unit address: (empty because#address-cells = <0>
in the open-pic node)parent interrupt specifier:2 1
- The child unit address is
<0x8800 0 0>
. This value is encoded with three 32-bit cells, which is determined by the value of the #address-cells property (value of 3) of the PCI controller. The three cells represent the PCI address as described by the binding for the PCI bus.- The encoding includes the bus number (0x0 << 16), device number (0x11 << 11), and function number (0x0 << 8).
- The child interrupt specifier is
<1>
, which specifies INTA as described by the PCI binding. This takes one 32-bit cell as specified by the #interrupt-cells property (value of 1) of the PCI controller, which is the child interrupt domain. - The interrupt parent is specified by a phandle which points to the interrupt parent of the slot, the Open PIC interrupt controller.
- The parent has no unit address because the parent interrupt domain
(the open-pic node) has an #address-cells value of
<0>
. - The parent interrupt specifier is
<2 1>
. The number of cells to represent the interrupt specifier (two cells) is determined by the #interrupt-cells property on the interrupt parent, the open-pic node.- The value
<2 1>
is a value specified by the device binding for the Open PIC interrupt controller (see section 4.5). The value<2>
specifies the physical interrupt source number on the interrupt controller to which INTA is wired. The value<1>
specifies the level/sense encoding.
- The value
- The child unit address is
In this example, the interrupt-map-mask property has a value of <0xf800
0 0 7>
. This mask is applied to a child unit interrupt specifier before
performing a lookup in the interruptmap table.
To perform a lookup of the open-pic interrupt source number for INTB for IDSEL 0x12 (slot 2), function 0x3, the following steps would be performed:
- The child unit address and interrupt specifier form the value
<0x9300 0 0 2>
.- The encoding of the address includes the bus number (0x0 << 16), device number (0x12 << 11), and function number (0x3 << 8).
- The interrupt specifier is 2, which is the encoding for INTB as per the PCI binding.
- The interrupt-map-mask value
<0xf800 0 0 7>
is applied, giving a result of<0x9000 0 0 2>
. - That result is looked up in the interrupt-map table, which maps to
the parent interrupt specifier
<4 1>
.