Chapter 4: Payload Handoff Format¶
Here we define the handoff information from Platform Init to Payload, which takes the form of an devicetree blob. This section describes the bindings used for each area addressed by this specification.
A devicetree is a tree data structure with nodes that describe the devices in a system. Each node has exactly one parent except for the root node, which has no parent. Each node has property/value pairs that describe the characteristics of the device being presented. Properties consist of a name and a value. Property names are strings of 1 to 31 characters. Property values are an array of zero or more bytes that contain information associated with the property.
The sections below show which nodes should be passed from Platform Init and its corresponding property / value. It does not change what is passed from the Payload to the OS, but it is intended to avoid interfering with it, i.e. it uses the same bindings where possible.
A pointer to the FIT is provided so that the running image can find other images it needs and find out where they were loaded.
Note that properties indicated as ‘u32 / u64’ have a size determined by the architecture, either 32 or 64 bits.
Note
Usage legend: R=Required, O=Optional, OR=Optional but Recommended, SD=See Definition
Many of these sections refer to the Devicetree Specification [DTspec].
4.1 Standard Properties and Property Values¶
4.1.1 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.
Here are list of standard value types defined by the DTSpec [DTspec]:
Value |
Description |
---|---|
|
Value is empty. Used for conveying true-false information, when the presence or absence of the property itself is sufficiently descriptive. |
|
A 32-bit integer in big-endian format. Example: the 32-bit value 0x11223344 would be represented in memory as:
|
|
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:
|
|
Strings are printable and null-terminated. Example: the string “hello” would be represented in memory as:
|
|
Format is specific to the property. See the property definition. |
|
A |
|
A list of Example: The string list “hello”,”world” would be represented in memory as:
|
4.1.2 Standard Properties¶
[DTspec] defines a list of standard properties that is commonly used across many DT nodes. Due to its enormous amount of details, please refer to [DTspec] Chapter 2.3 (Standard Properties) directly for the full details of each standard properties.
Here is a list of example standard properties:
compatible
model
phandle
status
#address-cells and #size-cells
reg
virtual-reg
ranges
dma-ranges
Here are the standard properties that are used for this spec:
4.1.2.1 #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.Here are some important notes:
The #address-cells and #size-cells properties are not inherited from ancestors in the devicetree. They shall be explicitly defined.
A spec-compliant boot program shall supply #address-cells and #size-cells on all nodes that have children.
If missing, it should be assumed that 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@4600 { 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).
4.1.2.2 reg¶
Property name: reg
Property value: <prop-encoded-array>
encoded as an arbitrary 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 the 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 has 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>;
4.1.2.3 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@4600 { 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 a 1024 KB 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.
4.1.2.4 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 is bus dependent 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).
4.2 UPL Devicetree Nodes¶
Here is the list of devicetree nodes for UPL usage:
4.2.1 Node: / (Root Node) (R)¶
Property |
Usage |
Value Type |
Definition |
---|---|---|---|
#address-cells |
R |
u32 |
Specifies the number of <u32> cells to represent the address in the reg property in children of root. |
#size-cells |
R |
u32 |
Specifies the number of <u32> cells to represent the size in the reg property in children of root. |
4.2.2 Node: /options/upl-params (R)¶
These are the generic parameters / settings of the UPL payload.
Property |
Usage |
Value Type |
Definition |
---|---|---|---|
compatible |
R |
string |
“upl” |
boot-mode |
O |
string list |
For supporting different Payload boot flows. These influence how the payload runs. Note that this is not intended to support multiple Payloads. This string list is not meant to be prescriptive and only serves as an example data handoff, as long as Payload is able to recognise the value. Furthermore, Payload is not required to support all of the boot modes. For boot modes those are not supported by Payload, Payload can just ignore them without any specific actions. This property could be further refined in the future revisions.
|
addr-width |
O |
u32 |
52 means host address width is 52 bits. 46 means address width is 46 bits. This is mainly used by Payloads when initializing page tables. This can avoid the payload needing to access the SoC directly to obtain this information. |
pci-enum-done |
O |
empty |
When pci-enum-done present, payload will skip PCI resource assignment and it will use pci-rb node information to create internal resource map to ensure no conflict usage of those in-used PCI resources during payload execution. When pci-enum-done not present, payload may do the PCI enumeration to assign resources basing on pci-rb node information, and could also create resource map too. In some payloads, a simple PCI enumeration may still be executed even with “pci-enum-done” to collect PCI device information and bind corresponding drivers to provide services and functionality. (for example, find out network controller and bind network driver to support network functionality) |
4.2.3 Node: /options/upl-image@<addr> (R)¶
The behavior of Platform Init when loading a FIT cannot always be known at build time. For example:
Platform Init may select one of several configurations when loading the Payload; the configuration chosen may depend on the hardware that it is running on
Platform Init may load images to any address if there is no ‘load’ property in the image.
The Payload may need to know where one of the images ended up in memory, or which configuration was chosen. It cannot find this out by itself. The ‘image’ node provides information to help with these problems.
Property |
Usage |
Value Type |
Definition |
---|---|---|---|
reg |
SD |
prop-encoded array |
Address and size of FIT image that was loaded and executed to reach this point. This is required if the Payload must have access to the FIT to operate, e.g., if Platform Init does not load the images to a new address. Otherwise, it is optional. |
conf-offset |
O |
u32 |
Offset within FIT of the configuration node that was selected. |
4.2.4 Node: /options/upl-image/image@<addr> (O)¶
This node is only required if Platform Init loaded the images to different addresses. In the case where the FIT is used in-place, this is not needed.
The name of this node must match the name of the corresponding image node in the FIT. This provides information about the loaded images.
Each loaded image has a separate node created with the following properties:
Property |
Usage |
Value Type |
Definition |
---|---|---|---|
reg |
R |
prop-encoded array |
Address and size that the image was actually loaded to. This is normally the same as the image load address within the FIT, but can be different if anything was relocated, or if the FIT did not provide a load address. |
offset |
O |
u32 |
Offset within FIT of the image node for this image. |
description |
R |
string |
Description value for this image from the FIT. |
4.2.5 Node: /pci (R)¶
Payload may need below FDT nodes for collecting PCI devices information on the system for binding corresponding drivers to provide services and functionality.
There could be 2 or more root bridge nodes and even the same PCI segment may be shared by several root bridges. In this case ecam-base-addr in the PCI root bridge node is important for payload to know how to access each root bridge as well as what segment they belong to. (by masking bus/dev/func, the same ecam-base-addr will be the same segment root bridges).
Under each root bridge node, there could be several root ports and/or PCI devices listed as its child nodes. Please refer the example use case below for reference implementation.
The PCI bindings in this node must follow this specification - the IEEE Std 1275-1994 Standard for Boot (Initialization Configuration) Firmware [PCIBusBinding] with some restrictions.
As the #address-cells is always 3, the child / PCI address has to be presented in this format, per PCI Bus Binding spec [PCIBusBinding]:
The non-prefetchable and prefetchable memory windows must each be exactly 256MB (0x10000000) in size.
The prefetchable memory window must be immediately adjacent to the non-prefetcable memory window.
Here is a bitmap of the 3-cell address which is followed by the explanation of each bit:
Cell 1: npt000ss bbbbbbbb dddddfff rrrrrrrr
Cell 2: hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh
Cell 3: llllllll llllllll llllllll llllllll
Notes:
n: 0 if the address is relocatable, 1 otherwise
p: 1 if the addressable region is “prefetchable”, 0 otherwise
t: 1 if the address is aliased (for non-relocatable I/O), below 1 MB (for Memory), or below 64 KB (for relocatable I/O)
ss: space code
00: configuration space
01: I/O space
10: 32 bit memory space
11: 64 bit memory space
bbbbbbbb: The PCI bus number
ddddd: The device number
fff: The function number
rrrrrrrr: Register number. Not used.
Property Name |
Usage |
Value Type |
Definition |
---|---|---|---|
compatible |
R |
string list |
To determine what kind of driver should be applied to the device. It should be in the form of <manufacturer>,<model>. But for historical reason, <model> alone also works for common used devices. For this spec, ‘pci-rb’ is recommended to specify it is a PCI root brige node. |
#address-cells |
R |
u32 |
Indicates the number of cells used in addresses in the handoff. Per PCI Bus Binding spec [PCIBusBinding], this value must be 3. |
#size-cells |
R |
u32 |
Indicates the number of cells used for sizes in the handoff. Per PCI Bus Binding spec [PCIBusBinding], this value must be 2. |
bus-range |
SD |
prop-encoded-array |
Contains 2 cells, each encoded as with encode-int, the first representing the loweest bus number of the PCI bus implemented by the bus controller represented by this node (the secondary bus number in PCI-to-PCI bridge nomenclature), and the second representing the largest bus number of any PCI bus in the portion of the PCI domain that is subordinate to this node (the subordinate bus number in PCI-to-PCI bridge nomenclature). This is required for Payload to do a simple PCI scan to build a PCI device database for providing functionality/service drivers (graphics, USB, SATA…) This property is mandatory for a PCI root bridge node. |
reg |
R |
prop-encoded-array |
Refer to here for generic definition: 4.1.2.2 reg Indicates an address range that are used by the PCI devices under the current bridge. It is a range that the CPU (parent bus) can access. The form of reg is <[address1 size1] [address2 size2] [address3 size3] …>. As the reg data presents the address range in the parent memory space, so it is the parent’s cell count of address and size used. |
ranges |
SD |
prop-encoded-array or empty |
Refer to here for generic definition: 4.1.2.3 ranges For this node, ranges data is in the form of PCI address, CPU address, PCI size. The cells of PCI address is the value of #address-cells in PCI node (3). The cells of CPU address is the value of #address-cells in the parent node. The cells of PCI size is the value of #size-cells in PCI node (2). The data is used to define IO, prefetchable/non-prefetchable MMIO resources that can be utilized for the root bridge which can be assigned to downstream devices. The ranges include those MMIO or IO which are already assigned to downstream devices and available for future new devices. 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. |
dma-ranges |
O |
prop-encoded-array or empty |
Refer to here for generic definition: 4.1.2.4 dma-ranges Define the DMA address width capability of the root bridge. If only below 4GB region was defined, the payload may assume above 4GB DMA is not supported. |
An example showing multiple top-level PCI nodes each with its own bus range:
//1st pci-rb in its separate segment of PCIEXBAR 0xC0000000
pci-rb0@c0000000 {
compatible = "pci-rb";
#address-cells = <3>;
#size-cells = <2>;
bus-range = <0x01 0xdf>;
reg = <0x0 0xc0000000 0x1 0x0000000>; // whole ECAM region in this root bridge
ranges = <...>;
//several root ports
//properties
};
// 2nd pci-rb in the shared segment base of PCIEXBAR 0xE0000000
pci-rb1@e0000000 {
compatible = "pci-rb";
#address-cells = <3>;
#size-cells = <2>;
bus-range = <0x24 0x4b>;
reg = <0x0 0xe0000000 0x0 0x8000000>; //whole ECAM region in this root bridge
//non-reloc/non-prefetch/mmio, child-addr, parent-addr, length
ranges = <0x82000000 0x0 0x92000000 0x0 0x92000000 0x0 0x10BC0000
//non-reloc/non-prefetch/mmio, child-addr, parent-addr, length
0x82000000 0x2040 0x00000000 0x2040 0x00000000 0x1 0x40000000
//non-reloc/32bit/io, child-addr, parent-addr, length
0x81000000 0x0 0x4000 0x0 0x4000 0x0 0x2000>;
//non-reloc/non-prefetch/memory, child-addr, parent-addr, length
//indicate rb1 does not support above 4GB DMA
dma-ranges = <0x82000000 0x0 0x0 0x0 0x0 0x1 0x0>; // 0 ~ 4GB
//first root port is B0:D0:F0
rootport0@0,0 {
#address-cells = <3>;
#size-cells = <2>;
reg = <...>;
/* MMIO, IO resource assigned to this root port that can be consumed by
its downstream devices. */
ranges;
};
};
/* The 3rd pci-rb in the shared segment base of PCIEXBAR 0xE0000000 (starting
from 0xE8000000) */
pci-rb2@e8000000 {
compatible = "pci-rb";
#address-cells = <3>;
#size-cells = <2>;
bus-range = <0x81 0xc8>;
reg = <0x0 0xe8000000 0x0 0x8000000>; //whole ECAM region in this root bridge
//MMIO, IO resource owned by this root bridge
ranges = <...>;
//non-reloc/non-prefetch/memory, child-addr, parent-addr, length
//indicate rb2 does not support above 4GB DMA
dma-ranges = <0x82000000 0x0 0x0 0x0 0x0 0x1 0x0>; // 0 ~ 4GB
//first root port is B128: D0: F0
rootport0@0,0 {
reg = <...>;
/* MMIO, IO resource assigned to this root port that can be consumed by
its downstream devices. */
ranges;
};
};
4.2.6 Node: /isa (O)¶
There are different kinds of buses each using their own addressing scheme. Among them are usually memory addresses, legacy I/O Ports and PCIe. In summary one needs to surround the node using legacy I/O ports with a “isa” bus node.
For clarification, this node can be used for LPC and eSPI devices, as from software pespective, both are ISA compatible.
Property Name |
Usage |
Value Type |
Definition |
---|---|---|---|
compatible |
R |
string |
“isa” |
#address-cells |
R |
u32 |
2 |
#size-cells |
R |
u32 |
1 |
ranges |
SD |
prop-encoded-array or empty |
Refer to here for generic definition: 4.1.2.3 ranges Required for memory accesses or memory mapped I/O space. Optional if only indirect I/O is supported. Not required for legacy I/O. |
Specific legacy I/O devices are descirbed in child nodes. For UPL usage, only serial console is supported for now - further legacy I/O devices can be expended later if required. Please refer to 4.2.7 Node: Serial Console Device (SD) for serial console use cases.
For its child node, ‘reg’ property is required, and it is in the format of: <(enum) (address) (size)>; and here is the usage for the enum: * 0x0 # memory address * 0x1 # I/O address
4.2.7 Node: Serial Console Device (SD)¶
This refers to the debug / log console, where Payload can setup and use the same UART controller as Platform Init for seamless debug output. There can be more than one UART controller defined, and the ‘/chosen’ node must include a ‘stdout-path’ property pointing to this device when it is used, as per [DTspec].
This node is mandatory if a serial device is available and initialized by Platform Init.
Property Name |
Usage |
Value Type |
Definition |
---|---|---|---|
compatible |
R |
string list |
Compatible string for hardware. Currently, these compatible strings are supported: ns16550a, ns16550, ns8250, ns16450 |
clock-frequency |
R |
u32 |
Frequency (in Hz) of the baud rate generator’s input clock. |
current-speed |
R |
u32 |
Current serial device speed in bits per second. |
reg |
R |
prop-encoded-array |
Physical address of the registers device within the address space of the parent. The form of reg is <[address] [size]> |
reg-shift |
O |
u32 |
log2 of distance between the discrete device registers. If unspecified, the default value is 0, meaning 1 byte apart. |
reg-offset |
O |
u32 |
Offset of the registers from the base address. The default value is 0, meaning no offset. |
reg-io-width |
O |
u32 |
Register width in bytes. Valid values are 1, 2 and 4. The default value is 1, meaning byte width. |
virtual-reg |
SD |
u32 or u64 |
Specifies an effective address that maps to the first physical address specified in the reg property. This property is required if this device node is the system’s console. |
Example below shows a legacy I/O serial device and an MMIO serial device:
// Legacy I/O serial device
isa {
compatible = "isa";
#address-cells = <2>;
#size-cells = <1>;
serial@3f8 {
compatible = "ns16550";
reg-io-width = <1>;
reg = <1 0x3f8 8>;
clock-frequency = <0x1c2000>;
current-speed = <115200>;
};
};
// MMIO serial device
serial@fe037000 {
compatible = "ns16550a";
reg-io-width = <4>;
reg = /bits 64/ <0xfe037000 0x80>;
clock-frequency = <0x1c2000>;
current-speed = <1500000>;
};
Another example showing an MMIO serial device under PCI node:
pci-rb0 {
compatible = "pci";
#address-cells = <3>;
#size-cells = <2>;
...
serial@fe037000 {
compatible = "ns16550a";
reg-io-width = <4>;
//non-prefetchable, non-relocable, non-aliased 32bit MMIO
reg = <0x82000000 0 0xfe037000 0 0x80>;
clock-frequency = <0x1c2000>;
current-speed = <1500000>;
};
};
4.2.8 Node: framebuffer (for Display) (SD)¶
Normally only one framebuffer is provided in the handoff. It should be the ‘primary’ one (if such a concept exists in the system) and visible to the user. A ‘display0’ alias should provide the full path to the device. Where the device itself is not represented in the devicetree, the ‘display0’ alias should point to the simple-framebuffer node.
Look at the display0 alias. If this is a simple-framebuffer, then use that If not, search for a node with the “simple-framebuffer” compatible string, which has a ‘display’ property matching the display0 alias.
Note: If more than one framebuffer/ display device exist, the stdout-path in ‘chosen’ node must point to the freamebuffer node preferred to be used by the payload (in the case that only a single display output is supported by payload).
Property Name |
Usage |
Value Type |
Definition |
---|---|---|---|
compatible |
R |
string |
simple-framebuffer. |
reg |
R |
prop-encoded-array |
Graphic frame buffer’s base address and size. |
width |
R |
u32 |
pixels in the X dimension. |
height |
R |
u32 |
pixels in the Y dimension. |
stride |
R |
u32 |
bytes per line of pixels. |
format |
R |
string |
|
display |
R |
string |
Point to the PCI graphics device which provides this framebuffer as the primary display device. |
Example below shows how framebuffer node is generated:
Example 1 (non-PCI):
// Optional alias
aliases {
display0 = &framebuffer0;
};
framebuffer0: framebuffer@b0000000 {
compatible = "simple-framebuffer";
reg =<0x0 0xb0000000 0x040 0x500000>;
width = <1280>;
height = <1024>;
format = "a8r8g8b8";
};
Example 2: (PCI)
// Optional alias
aliases {
display0 = &gma;
};
pcie@10000000 {
compatible = "pci-host-ecam-generic";
reg = <...>
ranges = <...>;
pcie@8 {
/* Root port 00:01.0 */
reg = <0x00000800 0 0 0 0>;
ranges = <...>;
gma: gma@2,0 {
/* gfx device 01:00.0 */
reg = <0x00010000 0 0 0 0>;
};
};
};
framebuffer@b0000000 {
compatible = "simple-framebuffer";
reg = <0xb0000000>; // or use the BAR to access the framebuffer
// these likely come from EDID talking to the panel
width = <3840>;
height = <2160>;
format = "a8r8g8b8";
display = <&gma>;
};
4.2.9 Node: chosen (R)¶
For details about chosen node, please refer to [DTspec] Chapter 3.6 for the chosen node usage. For the UPL usecase, please refer to the example below:
Note
In this case the stdout is printed to two serial ports and one graphical framebuffer simultaneously.
chosen {
bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200";
stdout-path = "/soc/serial0", "/soc/serial1", "/soc/framebuffer1";
};
4.2.10 Node: /options/upl-custom (O)¶
Since the firmware sometimes might require additional/ customized information to be passed in due to some very specific use cases (for example, the vendor might add specific data to be consumed by Payload for specific setup or driver use cases like Intel CSME Features), hence custom nodes are allowed here for the flexibility. If the node data becomes common or popular enough in the future, we can create a separate node later for that node data.
4.2.11 Node: /memory (R)¶
The memory node is required to describe the physical-memory layout for the system. If a system has multiple ranges of memory, multiple memory nodes can be created, or the ranges can be specified in the reg property of a single memory node. See the Devicetree Specification (“/memory node” section) for details.
Property Name |
Usage |
Value Type |
Definition |
---|---|---|---|
device_type |
R |
string |
Value shall be ‘memory’ |
reg |
R |
prop-encoded- array |
Specify system memory region range. Consists of an arbitrary number of address and size pairs that specify the physical address and size of the memory ranges. |
initial-mapped-area |
O |
prop-encoded- array |
<u64 - effective address, u64 - physical address, u32 - size>. Specifies the address and size of the Initial Mapped Area. |
hotpluggable |
O |
boolean |
Specifies an explicit hint to the operating system that this memory may potentially be removed later. |
ecc-detection-bits |
O |
u32 |
If present, this indicates the number of bits of memory error which can be detected and reported by the Error- Correction Code (ECC) memory subsystem (typically 0, 1 or 2) |
ecc-correction-bits |
O |
u32 |
If present, this indicates the number of bits of memory error which can be corrected by the Error-Correction Code (ECC) memory subsystem (typically 0, 1 or 2) |
Example:
#address-cells = 2;
#size-cells = 2;
memory@0 {
reg = /bits 64/ <0x00 0xa0000>;
device_type = "memory";
};
memory@100000 {
reg = /bits 64/ <0x100000 0x500000>;
device_type = "memory";
ecc-detection-bits = <1>;
ecc-correction-bits = <1>;
};
memory@500000 {
reg = /bits 64/ <0x500000 0x5e8d0000>;
device_type = "memory";
};
Example:
#address-cells = 2;
#size-cells = 2;
memory@000000000 {
device_type = "memory";
reg = /bits 64/ < 0x000000000 0x80000000 >;
attribute = < 0x0000000000000001 >;
};
memory@1000000000 {
device_type = "memory";
reg = < 0x000000001 0x00000000 0x00000001 0x00000000 >;
attribute = < 0x0000000000000000 >;
};
4.2.12 Node: reserved-memory (R)¶
Both the reserved memory description models, namely simple descriptor (Memory Reservation Block) and standard descriptor (reserved memory node) are supported to provide information about memory which is not available for use. Payload shall exclude reserved memory from normal usage.
If Memory Reservation Block is used, payload is free to chose default attributes it wants to assign to this block. What is guaranteed is that this memory will be provided to OS as “reserved” memory. No memory optimisations (such as reclaim etc.) will be possible. On the other hand, standard reserved memory node will provide better control over memory range handling in firmware.
For further information on Memory Reservation Block, please refer to [DTspec] Chapter 5.3.
Here are the table description for standard reserved memory node. 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.
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.
Property Name |
Usage |
Value Type |
Definition |
---|---|---|---|
#address-cells |
R |
u32 |
Refer to here for generic definition: 4.1.2.1 #address-cells and #size-cells |
#size-cells |
R |
u32 |
Refer to here for generic definition: 4.1.2.1 #address-cells and #size-cells |
ranges |
SD |
prop-encoded-array or empty |
Refer to here for generic definition: 4.1.2.3 ranges |
Child Node:
Property Name |
Usage |
Value Type |
Definition |
---|---|---|---|
reg |
R |
u32 / 64 array |
Specify memory region of reserved memory |
no-map |
O |
boolean |
If present, indicates the operating system must not create a virtual mapping of the region |
compatible |
O |
string list |
See definition below |
Compatible string list for Child Node:
This is used to describe memory type for UPL usage. One of the example usage is that Payload will be aware of where pre-installed ACPI tables or NVS regions are and will adopt them for supporting additional ACPI table installation from payload phase. Those boot-code / boot-data regions from Platform Init will be reported to OS as usable memory without waste. Similarly, runtime-code / runtime-data may be provided by Platform Init for supporting firmware runtime services that will be used by OS. All of the below are optional and can be skipped if unsupported by the platform.
Compatible string
Description
acpi
Memory that holds ACPI tables
acpi-nvs
ACPI NVS buffer information
boot-code
Memory that holds firmware phase drivers and will be released to the OS when firmware boot phase finishes (for example with a UEFI payload when ExitBootService signaled).
boot-data
Memory that holds firmware phase data consumed by drivers and will be released to the OS when firmware boot phase finishes (for example with a UEFI payload when ExitBootService signaled).
runtime-code
Runtime service code memory region which will be used by OS runtime services.
runtime-data
Runtime service data memory region which will be used by OS runtime services.
special-purpose
Specific-purpose memory (e.g.: HBM or CXL). The memory is earmarked for specific purposes such as for specific device drivers or applications.
This attribute serves as a hint to the OS to avoid allocating this memory for core OS data or code that can not be relocated. Prolonged use of this memory for purposes other than the intended purpose may result in suboptimal platform performance.
smbios
If Platform Init has created a SMBIOS data buffer, this will have the SMBIOS data buffer region information. SMBIOS 3.0 or above must be supported by payload.
Example:
reserved-memory {
#size-cells = <0x02>;
#address-cells = <0x02>;
mmio@fe000000 {
reg = <0x00 0xfe000000 0x00 0x1000000>;
};
memory@78000000 {
reg = <0x00 0x78000000 0x00 0x8000000>;
no-map;
};
memory@a0000 {
reg = <0x00 0xa0000 0x00 0x60000>;
no-map;
};
memory@47168000 {
compatible = "acpi";
reg = <0x00 0x47168000 0x00 0x90000>;
};
memory@471f8000 {
compatible = "acpi-nvs";
reg = <0x00 0x471F8000 0x00 0x8000>;
};
};