|
| 1 | +.. _soc_porting_guide: |
| 2 | + |
| 3 | +SoC Porting Guide |
| 4 | +################### |
| 5 | + |
| 6 | +To add Zephyr support for a new :term:`SoC`, you need a *SoC directory* with |
| 7 | +various files in it, and a SoC :file:`.dtsi` in |
| 8 | +:zephyr_file:`dts/<ARCH>/<VENDOR>` is required. |
| 9 | + |
| 10 | +SoC Definitions |
| 11 | +*************** |
| 12 | + |
| 13 | +It is expected that you are familiar with the board concept in Zephyr. |
| 14 | +A high level overview of the hardware support hierarchy and terms used in the |
| 15 | +Zephyr documentation can be seen in :ref:`hw_support_hierarchy`. |
| 16 | + |
| 17 | +For SoC porting, the most important terms are: |
| 18 | + |
| 19 | +- SoC: the exact system on a chip the board's CPU is part of. |
| 20 | +- SoC series: a group of tightly related SoCs. |
| 21 | +- SoC family: a wider group of SoCs with similar characteristics. |
| 22 | +- CPU Cluster: a cluster of one or more CPU cores. |
| 23 | +- CPU core: a particular CPU instance of a given architecture. |
| 24 | +- Architecture: an instruction set architecture. |
| 25 | + |
| 26 | +Architecture |
| 27 | +============ |
| 28 | + |
| 29 | +See :ref:`architecture_porting_guide`. |
| 30 | + |
| 31 | + |
| 32 | +Create your SoC directory |
| 33 | +************************* |
| 34 | + |
| 35 | +Each SoC must have a unique name. Use the official name given by the SoC vendor |
| 36 | +and check that it's not already in use. In some cases someone else may have |
| 37 | +contributed a SoC with identical name. If the SoC name is already in use, then |
| 38 | +you should probably improve the existing SoC instead of creating a new one. |
| 39 | +The script ``list_hardware`` can be used to retrieve a list of all SoCs known |
| 40 | +in Zephyr, for example ``./scripts/list_hardware.py --soc-root=. --socs`` from |
| 41 | +the Zephyr base directory for a list of names that are already in use. |
| 42 | + |
| 43 | +Start by creating the directory ``zephyr/soc/<VENDOR>/soc1``, where |
| 44 | +``<VENDOR>`` is your vendor subdirectory. |
| 45 | + |
| 46 | +.. note:: |
| 47 | + A ``<VENDOR>`` subdirectory is mandatory if contributing your SoC |
| 48 | + to Zephyr, but if your SoC is placed in a local repo, then any folder |
| 49 | + structure under ``<your-repo>/soc`` is permitted. |
| 50 | + The ``<VENDOR>`` subdirectory must match a vendor defined in the list in |
| 51 | + :zephyr_file:`dts/bindings/vendor-prefixes.txt`. If the SoC vendor does not |
| 52 | + have a prefix in that list, then one must be created. |
| 53 | + |
| 54 | +.. note:: |
| 55 | + |
| 56 | + The SoC directory name does not need to match the name of the SoC. |
| 57 | + Multiple SoCs can even be defined in one directory. In Zephyr, SoCs are often |
| 58 | + organized in sub-folders in a common SoC Family or SoC Series tree. |
| 59 | + |
| 60 | +Your SoC directory should look like this: |
| 61 | + |
| 62 | +.. code-block:: none |
| 63 | +
|
| 64 | + soc/<VENDOR>/<soc-name> |
| 65 | + ├── soc.yml |
| 66 | + ├── soc.h |
| 67 | + ├── CMakeLists.txt |
| 68 | + ├── Kconfig |
| 69 | + ├── Kconfig.soc |
| 70 | + └── Kconfig.defconfig |
| 71 | +
|
| 72 | +Replace ``<soc-name>`` with your SoC's name. |
| 73 | + |
| 74 | + |
| 75 | +The mandatory files are: |
| 76 | + |
| 77 | +#. :file:`soc.yml`: a YAML file describing the high-level meta data of the |
| 78 | + SoC such as: |
| 79 | + - SoC name: the name of the SoC |
| 80 | + - CPU clusters: CPU clusters if the SoC contains one or more clusters |
| 81 | + - SoC series: the SoC series to which the SoC belong |
| 82 | + - SoC family: the SoC family to which the series belong |
| 83 | + |
| 84 | +#. :file:`soc.h`: a header file which can be used to describe or provide |
| 85 | + configuration macros for the SoC. The :file:`soc.h` will often be included in |
| 86 | + drivers, sub-systems, boards, and other source code found in Zephyr. |
| 87 | + |
| 88 | +#. :file:`Kconfig.soc`: the base SoC configuration which defines a Kconfig SoC |
| 89 | + symbol in the form of ``config SOC_<soc-name>`` and provides the SoC name to |
| 90 | + the Kconfig ``SOC`` setting. |
| 91 | + If the ``soc.yml`` describes a SoC family and series, then those must also |
| 92 | + be defined in this file. Kconfig settings outside of the SoC tree must not be |
| 93 | + selected. To select general Zephyr Kconfig settings the :file:`Kconfig` file |
| 94 | + must be used. |
| 95 | + |
| 96 | +#. :file:`CMakeLists.txt`: CMake file loaded by the Zephyr build system. This |
| 97 | + CMake file can define additional include paths and/or source files to be used |
| 98 | + when a build targets the SoC. Also the base line linker script to use must be |
| 99 | + defined. |
| 100 | + |
| 101 | +The optional files are: |
| 102 | + |
| 103 | +- :file:`Kconfig`, :file:`Kconfig.defconfig` software configuration in |
| 104 | + :ref:`kconfig` format. These select the architecture and peripherals |
| 105 | + available. |
| 106 | + |
| 107 | +Write your SoC YAML |
| 108 | +********************* |
| 109 | + |
| 110 | +The SoC YAML file describes the SoC family, SoC series, and SoC at a high level. |
| 111 | + |
| 112 | +Detailed configurations, such as hardware description and configuration are done |
| 113 | +in devicetree and Kconfig. |
| 114 | + |
| 115 | +The skeleton of a simple SoC YAML file containing just one SoC is: |
| 116 | + |
| 117 | +.. code-block:: yaml |
| 118 | +
|
| 119 | + socs: |
| 120 | + - name: <soc1> |
| 121 | +
|
| 122 | +It is possible to have multiple SoC located in the SoC folder. |
| 123 | +For example if they belong to a common family or series it is recommended to |
| 124 | +locate such SoC in a common tree. |
| 125 | +Multiple SoCs and SoC series in a common folder can be described in the |
| 126 | +:file:`soc.yml` file as: |
| 127 | + |
| 128 | +.. code-block:: yaml |
| 129 | +
|
| 130 | + family: |
| 131 | + name: <family-name> |
| 132 | + series: |
| 133 | + - name: <series-1-name> |
| 134 | + socs: |
| 135 | + - name: <soc1> |
| 136 | + cpucluster: |
| 137 | + - name: <coreA> |
| 138 | + - name: <coreB> |
| 139 | + ... |
| 140 | + - name: <soc2> |
| 141 | + - name: <series-2-name> |
| 142 | + ... |
| 143 | +
|
| 144 | +
|
| 145 | +Write your SoC devicetree |
| 146 | +************************* |
| 147 | + |
| 148 | +SoC devicetree include files are located in the :file:`<zephyr-repo>/dts` folder |
| 149 | +under a corresponding :file:`<ARCH>/<VENDOR>`. |
| 150 | + |
| 151 | +The SoC :file:`dts/<ARCH>/<VENDOR>/<soc>.dtsi` describes your SoC hardware in |
| 152 | +the Devicetree Source (DTS) format and must be included by any boards which use |
| 153 | +the SoC. |
| 154 | + |
| 155 | +If a highlevel :file:`<arch>.dtsi` file exists, then a good starting point is to |
| 156 | +include this file in your :file:`<soc>.dtsi`. |
| 157 | + |
| 158 | +In general, :file:`<soc>.dtsi` should look like this: |
| 159 | + |
| 160 | +.. code-block:: devicetree |
| 161 | +
|
| 162 | + #include <arch>/<arch>.dtsi |
| 163 | +
|
| 164 | + / { |
| 165 | + chosen { |
| 166 | + /* common chosen settings for your SoC */ |
| 167 | + }; |
| 168 | +
|
| 169 | + cpus { |
| 170 | + #address-cells = <m>; |
| 171 | + #size-cells = <n>; |
| 172 | +
|
| 173 | + cpu@0 { |
| 174 | + device_type = "cpu"; |
| 175 | + compatible = "<compatibles>"; |
| 176 | + /* ... your CPU definitions ... */ |
| 177 | + }; |
| 178 | +
|
| 179 | + soc { |
| 180 | + /* Your SoC definitions and peripherals */ |
| 181 | + /* such as ram, clock, buses, peripherals. */ |
| 182 | + }; |
| 183 | + }; |
| 184 | +
|
| 185 | +.. hint:: |
| 186 | + It is possible to structure multiple :file:`<VENDOR>/<soc>.dtsi` files in |
| 187 | + sub-directories for a cleaner file system structure. For example organized |
| 188 | + pre SoC series, like this: :file:`<VENDOR>/<SERIES>/<soc>.dtsi`. |
| 189 | + |
| 190 | + |
| 191 | +Multiple CPU clusters |
| 192 | +===================== |
| 193 | + |
| 194 | +Devicetree reflects the hardware. The memory space and peripherals available to |
| 195 | +one CPU cluster can be very different from another CPU cluster, therefore each |
| 196 | +CPU cluster will often have its own :file:`.dtsi` file. |
| 197 | + |
| 198 | +CPU cluster :file:`.dtsi` files should follow the naming scheme |
| 199 | +:file:`<soc>_<cluster>.dtsi`. A :file:`<soc>_<cluster>.dtsi` file will look |
| 200 | +similar to a SoC :file:`.dtsi` without CPU clusters. |
| 201 | + |
| 202 | +Write Kconfig files |
| 203 | +******************* |
| 204 | + |
| 205 | +Zephyr uses the Kconfig language to configure software features. Your SoC |
| 206 | +needs to provide some Kconfig settings before you can compile a Zephyr |
| 207 | +application for it. |
| 208 | + |
| 209 | +Setting Kconfig configuration values is documented in detail in |
| 210 | +:ref:`setting_configuration_values`. |
| 211 | + |
| 212 | +There is one mandatory Kconfig file in the SoC directory, and two optional |
| 213 | +files for a SoC: |
| 214 | + |
| 215 | +.. code-block:: none |
| 216 | +
|
| 217 | + soc/<vendor>/<your soc> |
| 218 | + ├── Kconfig.soc |
| 219 | + ├── Kconfig |
| 220 | + └── Kconfig.defconfig |
| 221 | +
|
| 222 | +:file:`Kconfig.soc` |
| 223 | + A shared Kconfig file which can be sourced both in Zephyr Kconfig and sysbuild |
| 224 | + Kconfig trees. |
| 225 | + |
| 226 | + This file selects the SoC family and series in the Kconfig tree and potential |
| 227 | + other SoC related Kconfig settings. In some cases a SOC_PART_NUMBER. |
| 228 | + This file must not select anything outside the re-usable Kconfig SoC tree. |
| 229 | + |
| 230 | + A :file:`Kconfig.soc` may look like this: |
| 231 | + |
| 232 | + .. code-block:: kconfig |
| 233 | +
|
| 234 | + config SOC_<series name> |
| 235 | + bool |
| 236 | +
|
| 237 | + config SOC_<SOC_NAME> |
| 238 | + bool |
| 239 | + select SOC_SERIES_<series name> |
| 240 | +
|
| 241 | + config SOC |
| 242 | + default "SoC name" if SOC_<SOC_NAME> |
| 243 | +
|
| 244 | + Notice that ``SOC_NAME`` is a pure upper case version of the SoC name. |
| 245 | + |
| 246 | + The Kconfig ``SOC`` setting is globally defined as a string and therefore the |
| 247 | + :file:`Kconfig.soc` file shall only define the default string value and not |
| 248 | + the type. Notice that the string value must match the SoC name used in the |
| 249 | + :file:`soc.yml` file. |
| 250 | + |
| 251 | +:file:`Kconfig` |
| 252 | + Included by :zephyr_file:`soc/Kconfig`. |
| 253 | + |
| 254 | + This file can add Kconfig settings which are specific to the current SoC. |
| 255 | + |
| 256 | + The :file:`Kconfig` will often indicate given hardware support using a setting |
| 257 | + of the form ``HAS_<support>``. |
| 258 | + |
| 259 | + .. code-block:: kconfig |
| 260 | +
|
| 261 | + config SOC_<SOC_NAME> |
| 262 | + select ARM |
| 263 | + select CPU_HAS_FPU |
| 264 | +
|
| 265 | + If the setting name is identical to an existing Kconfig setting in Zephyr and |
| 266 | + only modifies the default value of said setting, then |
| 267 | + :file:`Kconfig.defconfig` should be used instead. |
| 268 | + |
| 269 | +:file:`Kconfig.defconfig` |
| 270 | + SoC specific default values for Kconfig options. |
| 271 | + |
| 272 | + Not all SoCs have a :file:`Kconfig.defconfig` file. |
| 273 | + |
| 274 | + The entire file should be inside a pair of ``if SOC_<SOC_NAME>`` / ``endif`` |
| 275 | + or ``if SOC_SERIES_<SERIES_NAME>`` / ``endif``, like this: |
| 276 | + |
| 277 | + .. code-block:: kconfig |
| 278 | +
|
| 279 | + if SOC_<SOC_NAME> |
| 280 | +
|
| 281 | + config NUM_IRQS |
| 282 | + default 32 |
| 283 | +
|
| 284 | + endif # SOC_<SOC_NAME> |
| 285 | +
|
| 286 | +Multiple CPU clusters |
| 287 | +===================== |
| 288 | + |
| 289 | +CPU clusters must provide additional Kconfig settings in the :file:`Kconfig.soc` |
| 290 | +file. This will usually be in the form of ``SOC_<SOC_NAME>_<CLUSTER>`` so for |
| 291 | +a given ``soc1`` with two clusters ``clusterA`` and ``clusterB``, then this |
| 292 | +will look like: |
| 293 | + |
| 294 | +SoC's When a SoC defines CPU cluster |
| 295 | + |
| 296 | + .. code-block:: kconfig |
| 297 | +
|
| 298 | + config SOC_SOC1_CLUSTERA |
| 299 | + bool |
| 300 | + select SOC_SOC1 |
| 301 | +
|
| 302 | + config SOC_SOC1_CLUSTERB |
| 303 | + bool |
| 304 | + select SOC_SOC1 |
0 commit comments