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