]> git.saurik.com Git - apple/xnu.git/blob - bsd/dev/arm/kern_machdep.c
9caed58b187234a13e741eda4f069c7f808da2c8
[apple/xnu.git] / bsd / dev / arm / kern_machdep.c
1 /*
2 * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
3 */
4 /*
5 * Copyright (C) 1990, NeXT, Inc.
6 *
7 * File: next/kern_machdep.c
8 * Author: John Seamons
9 *
10 * Machine-specific kernel routines.
11 */
12
13 #include <sys/types.h>
14 #include <mach/machine.h>
15 #include <kern/cpu_number.h>
16 #include <libkern/libkern.h>
17 #include <machine/exec.h>
18 #include <pexpert/arm64/board_config.h>
19
20 #if __arm64__
21 static cpu_subtype_t cpu_subtype32(void);
22 #endif /* __arm64__ */
23
24 #if __arm64__
25 /*
26 * When an arm64 CPU is executing an arm32 binary, we need to map from the
27 * host's 64-bit subtype to the appropriate 32-bit subtype.
28 */
29 static cpu_subtype_t
30 cpu_subtype32()
31 {
32 switch (cpu_subtype()) {
33 case CPU_SUBTYPE_ARM64_V8:
34 return CPU_SUBTYPE_ARM_V8;
35 default:
36 return 0;
37 }
38 }
39
40 #endif /* __arm64__ */
41
42 /**********************************************************************
43 * Routine: grade_binary()
44 *
45 * Function: Return a relative preference for exectypes and
46 * execsubtypes in fat executable files. The higher the
47 * grade, the higher the preference. A grade of 0 means
48 * not acceptable.
49 **********************************************************************/
50 int
51 grade_binary(cpu_type_t exectype, cpu_subtype_t execsubtype, cpu_subtype_t execfeatures __unused, bool allow_simulator_binary __unused)
52 {
53 #if __arm64__
54 cpu_subtype_t hostsubtype =
55 (exectype & CPU_ARCH_ABI64) ? cpu_subtype() : cpu_subtype32();
56 #else
57 cpu_subtype_t hostsubtype = cpu_subtype();
58 #endif /* __arm64__ */
59
60 switch (exectype) {
61 #if __arm64__
62 case CPU_TYPE_ARM64:
63 switch (hostsubtype) {
64 case CPU_SUBTYPE_ARM64_V8:
65 switch (execsubtype) {
66 case CPU_SUBTYPE_ARM64_V8:
67 return 10;
68 case CPU_SUBTYPE_ARM64_ALL:
69 return 9;
70 }
71 break;
72
73 } /* switch (hostsubtype) */
74 break;
75
76 #else /* __arm64__ */
77
78 case CPU_TYPE_ARM:
79 switch (hostsubtype) {
80 /*
81 * For 32-bit ARMv8, try the ARMv8 slice before falling back to Swift.
82 */
83 case CPU_SUBTYPE_ARM_V8:
84 switch (execsubtype) {
85 case CPU_SUBTYPE_ARM_V8:
86 return 7;
87 }
88 goto v7s;
89
90 /*
91 * For Swift and later, we prefer to run a swift slice, but fall back
92 * to v7 as Cortex A9 errata should not apply
93 */
94 v7s:
95 case CPU_SUBTYPE_ARM_V7S:
96 switch (execsubtype) {
97 case CPU_SUBTYPE_ARM_V7S:
98 return 6;
99 }
100 goto v7;
101
102 /*
103 * For Cortex A7, accept v7k only due to differing ABI
104 */
105 case CPU_SUBTYPE_ARM_V7K:
106 switch (execsubtype) {
107 case CPU_SUBTYPE_ARM_V7K:
108 return 6;
109 }
110 break;
111
112 /*
113 * For Cortex A9, we prefer the A9 slice, but will run v7 albeit
114 * under the risk of hitting the NEON load/store errata
115 */
116 case CPU_SUBTYPE_ARM_V7F:
117 switch (execsubtype) {
118 case CPU_SUBTYPE_ARM_V7F:
119 return 6;
120 }
121 goto v7;
122
123 v7:
124 case CPU_SUBTYPE_ARM_V7:
125 switch (execsubtype) {
126 case CPU_SUBTYPE_ARM_V7:
127 return 5;
128 }
129 // fall through...
130
131 case CPU_SUBTYPE_ARM_V6:
132 switch (execsubtype) {
133 case CPU_SUBTYPE_ARM_V6:
134 return 4;
135 }
136 // fall through...
137
138 case CPU_SUBTYPE_ARM_V5TEJ:
139 switch (execsubtype) {
140 case CPU_SUBTYPE_ARM_V5TEJ:
141 return 3;
142 }
143 // fall through
144
145 case CPU_SUBTYPE_ARM_V4T:
146 switch (execsubtype) {
147 case CPU_SUBTYPE_ARM_V4T:
148 return 2;
149 case CPU_SUBTYPE_ARM_ALL:
150 return 1;
151 }
152 break;
153
154 case CPU_SUBTYPE_ARM_XSCALE:
155 switch (execsubtype) {
156 case CPU_SUBTYPE_ARM_XSCALE:
157 return 4;
158 case CPU_SUBTYPE_ARM_V5TEJ:
159 return 3;
160 case CPU_SUBTYPE_ARM_V4T:
161 return 2;
162 case CPU_SUBTYPE_ARM_ALL:
163 return 1;
164 }
165 break;
166 }
167 #endif /* __arm64__ */
168 }
169
170 return 0;
171 }