]> git.saurik.com Git - apple/xnu.git/blob - bsd/dev/arm/kern_machdep.c
695c74ff0ec8de794dd9cab61a0b70201351ec69
[apple/xnu.git] / bsd / dev / arm / kern_machdep.c
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
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>
18
19 #if __arm64__
20 extern int bootarg_no64exec; /* bsd_init.c */
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 /**********************************************************************
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 **********************************************************************/
49 int
50 grade_binary(cpu_type_t exectype, cpu_subtype_t execsubtype)
51 {
52 #if __arm64__
53 cpu_subtype_t hostsubtype =
54 (exectype & CPU_ARCH_ABI64) ? cpu_subtype() : cpu_subtype32();
55 #else
56 cpu_subtype_t hostsubtype = cpu_subtype();
57 #endif /* __arm64__ */
58
59 switch (exectype) {
60 #if __arm64__
61 case CPU_TYPE_ARM64:
62 if (bootarg_no64exec) {
63 return 0;
64 }
65
66 switch (hostsubtype) {
67 case CPU_SUBTYPE_ARM64_V8:
68 switch (execsubtype) {
69 case CPU_SUBTYPE_ARM64_V8:
70 return 10;
71 case CPU_SUBTYPE_ARM64_ALL:
72 return 9;
73 }
74 break;
75
76 } /* switch (hostsubtype) */
77
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
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 */
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 }
112 break;
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 }
131 // fall through...
132
133 case CPU_SUBTYPE_ARM_V6:
134 switch (execsubtype) {
135 case CPU_SUBTYPE_ARM_V6:
136 return 4;
137 }
138 // fall through...
139
140 case CPU_SUBTYPE_ARM_V5TEJ:
141 switch (execsubtype) {
142 case CPU_SUBTYPE_ARM_V5TEJ:
143 return 3;
144 }
145 // fall through
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) {
186 case CPU_SUBTYPE_ARM_V7K:
187 return TRUE;
188 }
189 break;
190 }
191 return FALSE;
192 }