xref: /xnu-8792.81.2/doc/xnu_build_consolidation.md (revision 19c3b8c28c31cb8130e034cfb5df6bf9ba342d90) !
1*19c3b8c2SApple OSS Distributions# XNU Build Consolidation
2*19c3b8c2SApple OSS Distributions
3*19c3b8c2SApple OSS Distributions## Introduction and motivation
4*19c3b8c2SApple OSS Distributions
5*19c3b8c2SApple OSS DistributionsXNU is supported on approximately 20 different targets. Whilst in some cases the differences between two
6*19c3b8c2SApple OSS Distributionsgiven targets are small (e.g. when they both support the same ISA), XNU has traditionally required to have
7*19c3b8c2SApple OSS Distributionsseparate builds in cases where the topology of the targets differ (for example, when they feature different
8*19c3b8c2SApple OSS Distributionscore/cluster counts or cache sizes). Similarly, SoC-specific fix-ups are usually conditionally compiled
9*19c3b8c2SApple OSS Distributionsbased on the target.
10*19c3b8c2SApple OSS Distributions
11*19c3b8c2SApple OSS DistributionsGiven the time it takes to compile all three different variants (release, debug and development) for each
12*19c3b8c2SApple OSS Distributionssupported SoC, usually several times a day for various teams across Apple, the goal of this project was to
13*19c3b8c2SApple OSS Distributionsreduce the number of existing builds, as well as to set up a simple framework that makes it easier to share
14*19c3b8c2SApple OSS Distributionsbuilds across different SoCs moving forward.
15*19c3b8c2SApple OSS Distributions
16*19c3b8c2SApple OSS DistributionsAlthough this effort could be extended to KEXTs, and hence lead to shared KernelCaches across devices, the
17*19c3b8c2SApple OSS Distributionsscope of this document only includes XNU. In cases where KEXTs also differ across targets, or perhaps the
18*19c3b8c2SApple OSS Distributionsrequired KEXTs are completely different in the first place, the kernel still needs to be linked
19*19c3b8c2SApple OSS Distributionsappropriately with different sets of KEXTs and hence KernelCaches cannot be shared.
20*19c3b8c2SApple OSS Distributions
21*19c3b8c2SApple OSS Distributions
22*19c3b8c2SApple OSS Distributions## Changes required in XNU
23*19c3b8c2SApple OSS Distributions
24*19c3b8c2SApple OSS DistributionsThe kernel itself is relatively SoC-agnostic, although strongly architecture-dependent; this is because most
25*19c3b8c2SApple OSS Distributionsof the SoC-specific aspects of the KernelCache are abstracted by the KEXTs. Things that pertain to the
26*19c3b8c2SApple OSS Distributionskernel include:
27*19c3b8c2SApple OSS Distributions
28*19c3b8c2SApple OSS Distributions* Number of cores/clusters in the system, their physical IDs and type.
29*19c3b8c2SApple OSS Distributions* Addresses of PIO registers that are to be accessed from the XNU side.
30*19c3b8c2SApple OSS Distributions* L1/L2 cache geometry parameters (e.g. size, number of set/ways).
31*19c3b8c2SApple OSS Distributions* Just like other components, the kernel has its share of responsibility when it comes to setting up HID
32*19c3b8c2SApple OSS Distributionsregisters and applying fix-ups at various points during boot or elsewhere at runtime.
33*19c3b8c2SApple OSS Distributions* Certain kernel-visible architectural features are optional, which means that two same-generation SoCs may
34*19c3b8c2SApple OSS Distributionsstill differ in their feature set.
35*19c3b8c2SApple OSS Distributions
36*19c3b8c2SApple OSS DistributionsAll of these problems can be solved through a mix of relying more heavily on device tree information and
37*19c3b8c2SApple OSS Distributionsperforming runtime checks. The latter is possible because both the ARM architecture and the Apple's
38*19c3b8c2SApple OSS Distributionsextensions provide r/o registers that can be checked at runtime to discover supported features as well as
39*19c3b8c2SApple OSS Distributionsvarious CPU-specific parameters.
40*19c3b8c2SApple OSS Distributions
41*19c3b8c2SApple OSS Distributions### Obtaining cache geometry parameters at runtime
42*19c3b8c2SApple OSS Distributions
43*19c3b8c2SApple OSS DistributionsAlthough not often, the kernel may still require deriving, one way or another, parameters like cache sizes
44*19c3b8c2SApple OSS Distributionsand number of set/ways. XNU needs most of this information to perform set/way clean/invalidate operations.
45*19c3b8c2SApple OSS DistributionsPrior to this work, these values were hardcoded for each supported target in `proc_reg.h`, and used in
46*19c3b8c2SApple OSS Distributions`caches_asm.s`. The ARM architecture provides the `CCSIDR_EL1` register, which can be used in conjunction
47*19c3b8c2SApple OSS Distributionswith `CSSELR_EL1` to select the target cache and obtain geometry information.
48*19c3b8c2SApple OSS Distributions
49*19c3b8c2SApple OSS Distributions
50*19c3b8c2SApple OSS Distributions### Performing CPU/Revision-specific checks at runtime
51*19c3b8c2SApple OSS Distributions
52*19c3b8c2SApple OSS DistributionsCPU and revision checks may be required at various places, although the focus here has been the application
53*19c3b8c2SApple OSS Distributionsof tunables at boot time.
54*19c3b8c2SApple OSS Distributions
55*19c3b8c2SApple OSS DistributionsTunables are often applied:
56*19c3b8c2SApple OSS Distributions
57*19c3b8c2SApple OSS Distributions* On a specific core type of a specific SoC.
58*19c3b8c2SApple OSS Distributions* On a subset of all of the CPU revisions.
59*19c3b8c2SApple OSS Distributions* On all P-cores or all E-cores.
60*19c3b8c2SApple OSS Distributions
61*19c3b8c2SApple OSS DistributionsThis has led in the past to a number of nested, conditionally-compiled blocks of code that are not easy to
62*19c3b8c2SApple OSS Distributionsunderstand or manage as new tunables are added or SoCs/revisions are deprecated.
63*19c3b8c2SApple OSS Distributions
64*19c3b8c2SApple OSS DistributionsThe changes applied as part of this work focus mainly on:
65*19c3b8c2SApple OSS Distributions
66*19c3b8c2SApple OSS Distributions1. Decoupling the tunable-application code from `start.s`.
67*19c3b8c2SApple OSS Distributions2. Splitting the tunable-application code across different files, one per supported architecture (e.g.
68*19c3b8c2SApple OSS Distributions`tunables_h7.h`, or `tunables_h11.h`).
69*19c3b8c2SApple OSS Distributions3. Providing "templates" for the most commonly-used combinations of tunables.
70*19c3b8c2SApple OSS Distributions4. Providing a family of assembly macros that can be used to conditionally execute code on a specific core
71*19c3b8c2SApple OSS Distributionstype, CPU ID, revision(s), or a combination of these.
72*19c3b8c2SApple OSS Distributions
73*19c3b8c2SApple OSS DistributionsAll of the macros live in the 64-bit version of `proc_reg.h`, and are SoC-agnostic; they simply check the
74*19c3b8c2SApple OSS Distributions`MIDR_EL1` register against a CPU revision that is passed as a parameter to the macro, where applicable.
75*19c3b8c2SApple OSS DistributionsSimilarly, where a block of code is to be executed on a core type, rather than a specific core ID, a couple
76*19c3b8c2SApple OSS Distributionsof the provided macros can check this against `MPIDR_EL1`.
77*19c3b8c2SApple OSS Distributions
78*19c3b8c2SApple OSS Distributions
79*19c3b8c2SApple OSS Distributions### Checking for feature compatibility at runtime
80*19c3b8c2SApple OSS Distributions
81*19c3b8c2SApple OSS DistributionsSome architectural features are optional, which means that, when disabled at compile-time, this may cause
82*19c3b8c2SApple OSS Distributionstwo same-generation SoCs to diverge.
83*19c3b8c2SApple OSS Distributions
84*19c3b8c2SApple OSS Distributions
85*19c3b8c2SApple OSS DistributionsRather than disabling features, and assuming this does not pose security risks or performance regressions,
86*19c3b8c2SApple OSS Distributionsthe preferred approach is to compile them in, but perform runtime checks to enable/disable them, possibly in
87*19c3b8c2SApple OSS Distributionsearly boot. The way these checks are performed varies from feature to feature (for example, VHE is an ARM
88*19c3b8c2SApple OSS Distributionsfeature, and the ARM ARM specifies how it can be discovered). For Apple-specific features, these are all
89*19c3b8c2SApple OSS Distributionsadvertised through the `AIDR_EL1` register. One of the changes is the addition of a function,
90*19c3b8c2SApple OSS Distributionsml_feature_supported(), that may be used to check for the presence of a feature at runtime.
91*19c3b8c2SApple OSS Distributions
92*19c3b8c2SApple OSS Distributions
93*19c3b8c2SApple OSS Distributions### Deriving core/cluster counts from device tree
94*19c3b8c2SApple OSS Distributions
95*19c3b8c2SApple OSS DistributionsOne of the aspects that until now has been hardcoded in XNU is the system topology: number of cores/clusters
96*19c3b8c2SApple OSS Distributionsand their physical IDs. This effort piggybacks on other recent XNU changes which aimed to consolidate
97*19c3b8c2SApple OSS Distributionstopology-related information into XNU, by parsing it from the device tree and exporting it to KEXTs through
98*19c3b8c2SApple OSS Distributionswell-defined APIs.
99*19c3b8c2SApple OSS Distributions
100*19c3b8c2SApple OSS DistributionsChanges applied as part of the XNU consolidation project include:
101*19c3b8c2SApple OSS Distributions
102*19c3b8c2SApple OSS Distributions* Extending the `ml_*` API to extract cluster information from the topology parser. New APIs include the following:
103*19c3b8c2SApple OSS Distributions    * `ml_get_max_cluster_number()`
104*19c3b8c2SApple OSS Distributions    * `ml_get_cluster_count()`
105*19c3b8c2SApple OSS Distributions    * `ml_get_first_cpu_id()`
106*19c3b8c2SApple OSS Distributions* Removing hardcoded core counts (`CPU_COUNT`) and cluster counts (`ARM_CLUSTER_COUNT`) from XNU, and
107*19c3b8c2SApple OSS Distributionsreplacing them with `ml_*` calls.
108*19c3b8c2SApple OSS Distributions* Similarly, deriving CPU physical IDs from the topology parser.
109*19c3b8c2SApple OSS Distributions
110*19c3b8c2SApple OSS Distributions
111*19c3b8c2SApple OSS Distributions### Allocating memory that is core size/cluster size/cache size aligned
112*19c3b8c2SApple OSS Distributions
113*19c3b8c2SApple OSS DistributionsIn some cases, certain statically-allocated arrays/structures need to be cache line-aligned, or have one
114*19c3b8c2SApple OSS Distributionselement per core or cluster. Whilst this information is not known precisely at compile time anymore, the
115*19c3b8c2SApple OSS Distributionsfollowing macros have been added to provide a reasonably close upper bound:
116*19c3b8c2SApple OSS Distributions
117*19c3b8c2SApple OSS Distributions* `MAX_CPUS`
118*19c3b8c2SApple OSS Distributions* `MAX_CPU_CLUSTERS`
119*19c3b8c2SApple OSS Distributions* `MAX_L2_CLINE`
120*19c3b8c2SApple OSS Distributions
121*19c3b8c2SApple OSS DistributionsThese macros are defined in `board_config.h`, and should be set to the same value for a group of targets
122*19c3b8c2SApple OSS Distributionssharing a single build. Note that these no longer reflect actual counts and sizes, and the real values need
123*19c3b8c2SApple OSS Distributionsto be queried at runtime through the `ml_` API.
124*19c3b8c2SApple OSS Distributions
125*19c3b8c2SApple OSS DistributionsThe L1 cache line size is still hardcoded, and defined as `MMU_CLINE`. Since this value is always the same
126*19c3b8c2SApple OSS Distributionsand very often checked at various places across XNU and elsewhere, it made sense to keep it as a compile
127*19c3b8c2SApple OSS Distributionstime macro rather than relying on runtime checks.
128*19c3b8c2SApple OSS Distributions
129*19c3b8c2SApple OSS Distributions### Restrictions on conditional compilation
130*19c3b8c2SApple OSS Distributions
131*19c3b8c2SApple OSS DistributionsCurrently, a family of per-SoC macros are defined at build time to enable XNU to conditionally compile code
132*19c3b8c2SApple OSS Distributionsfor different targets. These are named `ARM[64]_BOARD_CONFIG_[TARGET_NAME]`, and have historically been used
133*19c3b8c2SApple OSS Distributionsin different places across the kernel; for example, when applying tunables, various fixes, or enabling
134*19c3b8c2SApple OSS Distributionsdisabling features. In order not to create divergences in the future across same-generation SoCs, but also
135*19c3b8c2SApple OSS Distributionsto keep the codebase consistent, the recommendation is to avoid the use of these macros whenever possible.
136*19c3b8c2SApple OSS Distributions
137*19c3b8c2SApple OSS DistributionsInstead, XNU itself defines yet another family of macros that are defined for all targets of a particular
138*19c3b8c2SApple OSS Distributionsgeneration. These are named after the P-CORE introduced by each (for example, `APPLEMONSOON`, or
139*19c3b8c2SApple OSS Distributions`APPLEVORTEX`), and are preferred over the SoC-specific ones. Where a generation macro is not enough to
140*19c3b8c2SApple OSS Distributionsprovide correctness (which happens, for example, when the code block at hand should not be executed on a
141*19c3b8c2SApple OSS Distributionsgiven SoC of the same family), appropriate runtime checks can be performed inside the conditionally-compiled
142*19c3b8c2SApple OSS Distributionscode block. `machine_read_midr()` and `get_arm_cpu_version()` may be used for this purpose.
143