0001 ===========================================
0002 CPU topology binding description
0003 ===========================================
0004
0005 ===========================================
0006 1 - Introduction
0007 ===========================================
0008
0009 In a SMP system, the hierarchy of CPUs is defined through three entities that
0010 are used to describe the layout of physical CPUs in the system:
0011
0012 - socket
0013 - cluster
0014 - core
0015 - thread
0016
0017 The bottom hierarchy level sits at core or thread level depending on whether
0018 symmetric multi-threading (SMT) is supported or not.
0019
0020 For instance in a system where CPUs support SMT, "cpu" nodes represent all
0021 threads existing in the system and map to the hierarchy level "thread" above.
0022 In systems where SMT is not supported "cpu" nodes represent all cores present
0023 in the system and map to the hierarchy level "core" above.
0024
0025 CPU topology bindings allow one to associate cpu nodes with hierarchical groups
0026 corresponding to the system hierarchy; syntactically they are defined as device
0027 tree nodes.
0028
0029 Currently, only ARM/RISC-V intend to use this cpu topology binding but it may be
0030 used for any other architecture as well.
0031
0032 The cpu nodes, as per bindings defined in [4], represent the devices that
0033 correspond to physical CPUs and are to be mapped to the hierarchy levels.
0034
0035 A topology description containing phandles to cpu nodes that are not compliant
0036 with bindings standardized in [4] is therefore considered invalid.
0037
0038 ===========================================
0039 2 - cpu-map node
0040 ===========================================
0041
0042 The ARM/RISC-V CPU topology is defined within the cpu-map node, which is a direct
0043 child of the cpus node and provides a container where the actual topology
0044 nodes are listed.
0045
0046 - cpu-map node
0047
0048 Usage: Optional - On SMP systems provide CPUs topology to the OS.
0049 Uniprocessor systems do not require a topology
0050 description and therefore should not define a
0051 cpu-map node.
0052
0053 Description: The cpu-map node is just a container node where its
0054 subnodes describe the CPU topology.
0055
0056 Node name must be "cpu-map".
0057
0058 The cpu-map node's parent node must be the cpus node.
0059
0060 The cpu-map node's child nodes can be:
0061
0062 - one or more cluster nodes or
0063 - one or more socket nodes in a multi-socket system
0064
0065 Any other configuration is considered invalid.
0066
0067 The cpu-map node can only contain 4 types of child nodes:
0068
0069 - socket node
0070 - cluster node
0071 - core node
0072 - thread node
0073
0074 whose bindings are described in paragraph 3.
0075
0076 The nodes describing the CPU topology (socket/cluster/core/thread) can
0077 only be defined within the cpu-map node and every core/thread in the
0078 system must be defined within the topology. Any other configuration is
0079 invalid and therefore must be ignored.
0080
0081 ===========================================
0082 2.1 - cpu-map child nodes naming convention
0083 ===========================================
0084
0085 cpu-map child nodes must follow a naming convention where the node name
0086 must be "socketN", "clusterN", "coreN", "threadN" depending on the node type
0087 (ie socket/cluster/core/thread) (where N = {0, 1, ...} is the node number; nodes
0088 which are siblings within a single common parent node must be given a unique and
0089 sequential N value, starting from 0).
0090 cpu-map child nodes which do not share a common parent node can have the same
0091 name (ie same number N as other cpu-map child nodes at different device tree
0092 levels) since name uniqueness will be guaranteed by the device tree hierarchy.
0093
0094 ===========================================
0095 3 - socket/cluster/core/thread node bindings
0096 ===========================================
0097
0098 Bindings for socket/cluster/cpu/thread nodes are defined as follows:
0099
0100 - socket node
0101
0102 Description: must be declared within a cpu-map node, one node
0103 per physical socket in the system. A system can
0104 contain single or multiple physical socket.
0105 The association of sockets and NUMA nodes is beyond
0106 the scope of this bindings, please refer [2] for
0107 NUMA bindings.
0108
0109 This node is optional for a single socket system.
0110
0111 The socket node name must be "socketN" as described in 2.1 above.
0112 A socket node can not be a leaf node.
0113
0114 A socket node's child nodes must be one or more cluster nodes.
0115
0116 Any other configuration is considered invalid.
0117
0118 - cluster node
0119
0120 Description: must be declared within a cpu-map node, one node
0121 per cluster. A system can contain several layers of
0122 clustering within a single physical socket and cluster
0123 nodes can be contained in parent cluster nodes.
0124
0125 The cluster node name must be "clusterN" as described in 2.1 above.
0126 A cluster node can not be a leaf node.
0127
0128 A cluster node's child nodes must be:
0129
0130 - one or more cluster nodes; or
0131 - one or more core nodes
0132
0133 Any other configuration is considered invalid.
0134
0135 - core node
0136
0137 Description: must be declared in a cluster node, one node per core in
0138 the cluster. If the system does not support SMT, core
0139 nodes are leaf nodes, otherwise they become containers of
0140 thread nodes.
0141
0142 The core node name must be "coreN" as described in 2.1 above.
0143
0144 A core node must be a leaf node if SMT is not supported.
0145
0146 Properties for core nodes that are leaf nodes:
0147
0148 - cpu
0149 Usage: required
0150 Value type: <phandle>
0151 Definition: a phandle to the cpu node that corresponds to the
0152 core node.
0153
0154 If a core node is not a leaf node (CPUs supporting SMT) a core node's
0155 child nodes can be:
0156
0157 - one or more thread nodes
0158
0159 Any other configuration is considered invalid.
0160
0161 - thread node
0162
0163 Description: must be declared in a core node, one node per thread
0164 in the core if the system supports SMT. Thread nodes are
0165 always leaf nodes in the device tree.
0166
0167 The thread node name must be "threadN" as described in 2.1 above.
0168
0169 A thread node must be a leaf node.
0170
0171 A thread node must contain the following property:
0172
0173 - cpu
0174 Usage: required
0175 Value type: <phandle>
0176 Definition: a phandle to the cpu node that corresponds to
0177 the thread node.
0178
0179 ===========================================
0180 4 - Example dts
0181 ===========================================
0182
0183 Example 1 (ARM 64-bit, 16-cpu system, two clusters of clusters in a single
0184 physical socket):
0185
0186 cpus {
0187 #size-cells = <0>;
0188 #address-cells = <2>;
0189
0190 cpu-map {
0191 socket0 {
0192 cluster0 {
0193 cluster0 {
0194 core0 {
0195 thread0 {
0196 cpu = <&CPU0>;
0197 };
0198 thread1 {
0199 cpu = <&CPU1>;
0200 };
0201 };
0202
0203 core1 {
0204 thread0 {
0205 cpu = <&CPU2>;
0206 };
0207 thread1 {
0208 cpu = <&CPU3>;
0209 };
0210 };
0211 };
0212
0213 cluster1 {
0214 core0 {
0215 thread0 {
0216 cpu = <&CPU4>;
0217 };
0218 thread1 {
0219 cpu = <&CPU5>;
0220 };
0221 };
0222
0223 core1 {
0224 thread0 {
0225 cpu = <&CPU6>;
0226 };
0227 thread1 {
0228 cpu = <&CPU7>;
0229 };
0230 };
0231 };
0232 };
0233
0234 cluster1 {
0235 cluster0 {
0236 core0 {
0237 thread0 {
0238 cpu = <&CPU8>;
0239 };
0240 thread1 {
0241 cpu = <&CPU9>;
0242 };
0243 };
0244 core1 {
0245 thread0 {
0246 cpu = <&CPU10>;
0247 };
0248 thread1 {
0249 cpu = <&CPU11>;
0250 };
0251 };
0252 };
0253
0254 cluster1 {
0255 core0 {
0256 thread0 {
0257 cpu = <&CPU12>;
0258 };
0259 thread1 {
0260 cpu = <&CPU13>;
0261 };
0262 };
0263 core1 {
0264 thread0 {
0265 cpu = <&CPU14>;
0266 };
0267 thread1 {
0268 cpu = <&CPU15>;
0269 };
0270 };
0271 };
0272 };
0273 };
0274 };
0275
0276 CPU0: cpu@0 {
0277 device_type = "cpu";
0278 compatible = "arm,cortex-a57";
0279 reg = <0x0 0x0>;
0280 enable-method = "spin-table";
0281 cpu-release-addr = <0 0x20000000>;
0282 };
0283
0284 CPU1: cpu@1 {
0285 device_type = "cpu";
0286 compatible = "arm,cortex-a57";
0287 reg = <0x0 0x1>;
0288 enable-method = "spin-table";
0289 cpu-release-addr = <0 0x20000000>;
0290 };
0291
0292 CPU2: cpu@100 {
0293 device_type = "cpu";
0294 compatible = "arm,cortex-a57";
0295 reg = <0x0 0x100>;
0296 enable-method = "spin-table";
0297 cpu-release-addr = <0 0x20000000>;
0298 };
0299
0300 CPU3: cpu@101 {
0301 device_type = "cpu";
0302 compatible = "arm,cortex-a57";
0303 reg = <0x0 0x101>;
0304 enable-method = "spin-table";
0305 cpu-release-addr = <0 0x20000000>;
0306 };
0307
0308 CPU4: cpu@10000 {
0309 device_type = "cpu";
0310 compatible = "arm,cortex-a57";
0311 reg = <0x0 0x10000>;
0312 enable-method = "spin-table";
0313 cpu-release-addr = <0 0x20000000>;
0314 };
0315
0316 CPU5: cpu@10001 {
0317 device_type = "cpu";
0318 compatible = "arm,cortex-a57";
0319 reg = <0x0 0x10001>;
0320 enable-method = "spin-table";
0321 cpu-release-addr = <0 0x20000000>;
0322 };
0323
0324 CPU6: cpu@10100 {
0325 device_type = "cpu";
0326 compatible = "arm,cortex-a57";
0327 reg = <0x0 0x10100>;
0328 enable-method = "spin-table";
0329 cpu-release-addr = <0 0x20000000>;
0330 };
0331
0332 CPU7: cpu@10101 {
0333 device_type = "cpu";
0334 compatible = "arm,cortex-a57";
0335 reg = <0x0 0x10101>;
0336 enable-method = "spin-table";
0337 cpu-release-addr = <0 0x20000000>;
0338 };
0339
0340 CPU8: cpu@100000000 {
0341 device_type = "cpu";
0342 compatible = "arm,cortex-a57";
0343 reg = <0x1 0x0>;
0344 enable-method = "spin-table";
0345 cpu-release-addr = <0 0x20000000>;
0346 };
0347
0348 CPU9: cpu@100000001 {
0349 device_type = "cpu";
0350 compatible = "arm,cortex-a57";
0351 reg = <0x1 0x1>;
0352 enable-method = "spin-table";
0353 cpu-release-addr = <0 0x20000000>;
0354 };
0355
0356 CPU10: cpu@100000100 {
0357 device_type = "cpu";
0358 compatible = "arm,cortex-a57";
0359 reg = <0x1 0x100>;
0360 enable-method = "spin-table";
0361 cpu-release-addr = <0 0x20000000>;
0362 };
0363
0364 CPU11: cpu@100000101 {
0365 device_type = "cpu";
0366 compatible = "arm,cortex-a57";
0367 reg = <0x1 0x101>;
0368 enable-method = "spin-table";
0369 cpu-release-addr = <0 0x20000000>;
0370 };
0371
0372 CPU12: cpu@100010000 {
0373 device_type = "cpu";
0374 compatible = "arm,cortex-a57";
0375 reg = <0x1 0x10000>;
0376 enable-method = "spin-table";
0377 cpu-release-addr = <0 0x20000000>;
0378 };
0379
0380 CPU13: cpu@100010001 {
0381 device_type = "cpu";
0382 compatible = "arm,cortex-a57";
0383 reg = <0x1 0x10001>;
0384 enable-method = "spin-table";
0385 cpu-release-addr = <0 0x20000000>;
0386 };
0387
0388 CPU14: cpu@100010100 {
0389 device_type = "cpu";
0390 compatible = "arm,cortex-a57";
0391 reg = <0x1 0x10100>;
0392 enable-method = "spin-table";
0393 cpu-release-addr = <0 0x20000000>;
0394 };
0395
0396 CPU15: cpu@100010101 {
0397 device_type = "cpu";
0398 compatible = "arm,cortex-a57";
0399 reg = <0x1 0x10101>;
0400 enable-method = "spin-table";
0401 cpu-release-addr = <0 0x20000000>;
0402 };
0403 };
0404
0405 Example 2 (ARM 32-bit, dual-cluster, 8-cpu system, no SMT):
0406
0407 cpus {
0408 #size-cells = <0>;
0409 #address-cells = <1>;
0410
0411 cpu-map {
0412 cluster0 {
0413 core0 {
0414 cpu = <&CPU0>;
0415 };
0416 core1 {
0417 cpu = <&CPU1>;
0418 };
0419 core2 {
0420 cpu = <&CPU2>;
0421 };
0422 core3 {
0423 cpu = <&CPU3>;
0424 };
0425 };
0426
0427 cluster1 {
0428 core0 {
0429 cpu = <&CPU4>;
0430 };
0431 core1 {
0432 cpu = <&CPU5>;
0433 };
0434 core2 {
0435 cpu = <&CPU6>;
0436 };
0437 core3 {
0438 cpu = <&CPU7>;
0439 };
0440 };
0441 };
0442
0443 CPU0: cpu@0 {
0444 device_type = "cpu";
0445 compatible = "arm,cortex-a15";
0446 reg = <0x0>;
0447 };
0448
0449 CPU1: cpu@1 {
0450 device_type = "cpu";
0451 compatible = "arm,cortex-a15";
0452 reg = <0x1>;
0453 };
0454
0455 CPU2: cpu@2 {
0456 device_type = "cpu";
0457 compatible = "arm,cortex-a15";
0458 reg = <0x2>;
0459 };
0460
0461 CPU3: cpu@3 {
0462 device_type = "cpu";
0463 compatible = "arm,cortex-a15";
0464 reg = <0x3>;
0465 };
0466
0467 CPU4: cpu@100 {
0468 device_type = "cpu";
0469 compatible = "arm,cortex-a7";
0470 reg = <0x100>;
0471 };
0472
0473 CPU5: cpu@101 {
0474 device_type = "cpu";
0475 compatible = "arm,cortex-a7";
0476 reg = <0x101>;
0477 };
0478
0479 CPU6: cpu@102 {
0480 device_type = "cpu";
0481 compatible = "arm,cortex-a7";
0482 reg = <0x102>;
0483 };
0484
0485 CPU7: cpu@103 {
0486 device_type = "cpu";
0487 compatible = "arm,cortex-a7";
0488 reg = <0x103>;
0489 };
0490 };
0491
0492 Example 3: HiFive Unleashed (RISC-V 64 bit, 4 core system)
0493
0494 {
0495 #address-cells = <2>;
0496 #size-cells = <2>;
0497 compatible = "sifive,fu540g", "sifive,fu500";
0498 model = "sifive,hifive-unleashed-a00";
0499
0500 ...
0501 cpus {
0502 #address-cells = <1>;
0503 #size-cells = <0>;
0504 cpu-map {
0505 socket0 {
0506 cluster0 {
0507 core0 {
0508 cpu = <&CPU1>;
0509 };
0510 core1 {
0511 cpu = <&CPU2>;
0512 };
0513 core2 {
0514 cpu0 = <&CPU2>;
0515 };
0516 core3 {
0517 cpu0 = <&CPU3>;
0518 };
0519 };
0520 };
0521 };
0522
0523 CPU1: cpu@1 {
0524 device_type = "cpu";
0525 compatible = "sifive,rocket0", "riscv";
0526 reg = <0x1>;
0527 }
0528
0529 CPU2: cpu@2 {
0530 device_type = "cpu";
0531 compatible = "sifive,rocket0", "riscv";
0532 reg = <0x2>;
0533 }
0534 CPU3: cpu@3 {
0535 device_type = "cpu";
0536 compatible = "sifive,rocket0", "riscv";
0537 reg = <0x3>;
0538 }
0539 CPU4: cpu@4 {
0540 device_type = "cpu";
0541 compatible = "sifive,rocket0", "riscv";
0542 reg = <0x4>;
0543 }
0544 }
0545 };
0546 ===============================================================================
0547 [1] ARM Linux kernel documentation
0548 Documentation/devicetree/bindings/arm/cpus.yaml
0549 [2] Devicetree NUMA binding description
0550 Documentation/devicetree/bindings/numa.txt
0551 [3] RISC-V Linux kernel documentation
0552 Documentation/devicetree/bindings/riscv/cpus.yaml
0553 [4] https://www.devicetree.org/specifications/