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