]>
Commit | Line | Data |
---|---|---|
5ba3f43e A |
1 | /* |
2 | * Copyright (c) 2000-2007 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 | ||
0a7de745 A |
13 | #include <sys/types.h> |
14 | #include <mach/machine.h> | |
15 | #include <kern/cpu_number.h> | |
16 | #include <machine/exec.h> | |
17 | #include <pexpert/arm64/board_config.h> | |
5ba3f43e A |
18 | |
19 | #if __arm64__ | |
0a7de745 | 20 | extern int bootarg_no64exec; /* bsd_init.c */ |
5ba3f43e A |
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 | #endif /* __arm64__*/ | |
40 | ||
41 | /********************************************************************** | |
0a7de745 A |
42 | * Routine: grade_binary() |
43 | * | |
44 | * Function: Return a relative preference for exectypes and | |
45 | * execsubtypes in fat executable files. The higher the | |
46 | * grade, the higher the preference. A grade of 0 means | |
47 | * not acceptable. | |
48 | **********************************************************************/ | |
5ba3f43e A |
49 | int |
50 | grade_binary(cpu_type_t exectype, cpu_subtype_t execsubtype) | |
51 | { | |
52 | #if __arm64__ | |
d9a64523 | 53 | cpu_subtype_t hostsubtype = |
0a7de745 | 54 | (exectype & CPU_ARCH_ABI64) ? cpu_subtype() : cpu_subtype32(); |
5ba3f43e A |
55 | #else |
56 | cpu_subtype_t hostsubtype = cpu_subtype(); | |
57 | #endif /* __arm64__ */ | |
58 | ||
59 | switch (exectype) { | |
60 | #if __arm64__ | |
61 | case CPU_TYPE_ARM64: | |
0a7de745 A |
62 | if (bootarg_no64exec) { |
63 | return 0; | |
64 | } | |
5ba3f43e A |
65 | |
66 | switch (hostsubtype) { | |
67 | case CPU_SUBTYPE_ARM64_V8: | |
68 | switch (execsubtype) { | |
69 | case CPU_SUBTYPE_ARM64_V8: | |
d9a64523 | 70 | return 10; |
5ba3f43e | 71 | case CPU_SUBTYPE_ARM64_ALL: |
d9a64523 | 72 | return 9; |
5ba3f43e A |
73 | } |
74 | break; | |
75 | ||
d9a64523 | 76 | } /* switch (hostsubtype) */ |
5ba3f43e | 77 | |
5ba3f43e A |
78 | #else /* __arm64__ */ |
79 | ||
80 | case CPU_TYPE_ARM: | |
81 | switch (hostsubtype) { | |
82 | /* | |
83 | * For 32-bit ARMv8, try the ARMv8 slice before falling back to Swift. | |
84 | */ | |
85 | case CPU_SUBTYPE_ARM_V8: | |
86 | switch (execsubtype) { | |
87 | case CPU_SUBTYPE_ARM_V8: | |
88 | return 7; | |
89 | } | |
90 | goto v7s; | |
91 | ||
0a7de745 A |
92 | /* |
93 | * For Swift and later, we prefer to run a swift slice, but fall back | |
94 | * to v7 as Cortex A9 errata should not apply | |
95 | */ | |
5ba3f43e A |
96 | v7s: |
97 | case CPU_SUBTYPE_ARM_V7S: | |
98 | switch (execsubtype) { | |
99 | case CPU_SUBTYPE_ARM_V7S: | |
100 | return 6; | |
101 | } | |
102 | goto v7; | |
103 | ||
104 | /* | |
105 | * For Cortex A7, accept v7k only due to differing ABI | |
106 | */ | |
107 | case CPU_SUBTYPE_ARM_V7K: | |
108 | switch (execsubtype) { | |
109 | case CPU_SUBTYPE_ARM_V7K: | |
110 | return 6; | |
111 | } | |
0a7de745 | 112 | break; |
5ba3f43e A |
113 | |
114 | /* | |
115 | * For Cortex A9, we prefer the A9 slice, but will run v7 albeit | |
116 | * under the risk of hitting the NEON load/store errata | |
117 | */ | |
118 | case CPU_SUBTYPE_ARM_V7F: | |
119 | switch (execsubtype) { | |
120 | case CPU_SUBTYPE_ARM_V7F: | |
121 | return 6; | |
122 | } | |
123 | goto v7; | |
124 | ||
125 | v7: | |
126 | case CPU_SUBTYPE_ARM_V7: | |
127 | switch (execsubtype) { | |
128 | case CPU_SUBTYPE_ARM_V7: | |
129 | return 5; | |
130 | } | |
0a7de745 | 131 | // fall through... |
5ba3f43e A |
132 | |
133 | case CPU_SUBTYPE_ARM_V6: | |
134 | switch (execsubtype) { | |
135 | case CPU_SUBTYPE_ARM_V6: | |
136 | return 4; | |
137 | } | |
0a7de745 | 138 | // fall through... |
5ba3f43e A |
139 | |
140 | case CPU_SUBTYPE_ARM_V5TEJ: | |
141 | switch (execsubtype) { | |
142 | case CPU_SUBTYPE_ARM_V5TEJ: | |
143 | return 3; | |
144 | } | |
0a7de745 | 145 | // fall through |
5ba3f43e A |
146 | |
147 | case CPU_SUBTYPE_ARM_V4T: | |
148 | switch (execsubtype) { | |
149 | case CPU_SUBTYPE_ARM_V4T: | |
150 | return 2; | |
151 | case CPU_SUBTYPE_ARM_ALL: | |
152 | return 1; | |
153 | } | |
154 | break; | |
155 | ||
156 | case CPU_SUBTYPE_ARM_XSCALE: | |
157 | switch (execsubtype) { | |
158 | case CPU_SUBTYPE_ARM_XSCALE: | |
159 | return 4; | |
160 | case CPU_SUBTYPE_ARM_V5TEJ: | |
161 | return 3; | |
162 | case CPU_SUBTYPE_ARM_V4T: | |
163 | return 2; | |
164 | case CPU_SUBTYPE_ARM_ALL: | |
165 | return 1; | |
166 | } | |
167 | break; | |
168 | } | |
169 | #endif /* __arm64__ */ | |
170 | } | |
171 | ||
172 | return 0; | |
173 | } | |
174 | ||
175 | boolean_t | |
176 | pie_required(cpu_type_t exectype, cpu_subtype_t execsubtype) | |
177 | { | |
178 | switch (exectype) { | |
179 | #if __arm64__ | |
180 | case CPU_TYPE_ARM64: | |
181 | return TRUE; | |
182 | #endif /* __arm64__ */ | |
183 | ||
184 | case CPU_TYPE_ARM: | |
185 | switch (execsubtype) { | |
0a7de745 A |
186 | case CPU_SUBTYPE_ARM_V7K: |
187 | return TRUE; | |
188 | } | |
5ba3f43e A |
189 | break; |
190 | } | |
191 | return FALSE; | |
192 | } |