Back to home page

OSCL-LXR

 
 

    


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/