xref: /xnu-11215.41.3/pexpert/gen/pe_gen.c (revision 33de042d024d46de5ff4e89f2471de6608e37fa4)
1 /*
2  * Copyright (c) 2000-2021 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  * @OSF_FREE_COPYRIGHT@
30  */
31 
32 #include <pexpert/pexpert.h>
33 #include <pexpert/protos.h>
34 #include <pexpert/device_tree.h>
35 #include <kern/debug.h>
36 
37 #include <libkern/section_keywords.h>
38 
39 #if CONFIG_SPTM
40 #include <sptm/sptm_xnu.h>
41 #endif
42 
43 #if defined(__arm64__)
44 SECURITY_READ_ONLY_LATE(static uint32_t) gPEKernelConfigurationBitmask;
45 #else
46 static uint32_t gPEKernelConfigurationBitmask;
47 #endif
48 
49 int32_t gPESerialBaud = -1;
50 
51 int debug_cpu_performance_degradation_factor = 1;
52 
53 void
pe_init_debug(void)54 pe_init_debug(void)
55 {
56 	boolean_t boot_arg_value;
57 
58 	gPEKernelConfigurationBitmask = 0;
59 
60 	if (!PE_parse_boot_argn("assertions", &boot_arg_value, sizeof(boot_arg_value))) {
61 #if MACH_ASSERT
62 		boot_arg_value = TRUE;
63 #else
64 		boot_arg_value = FALSE;
65 #endif
66 	}
67 	gPEKernelConfigurationBitmask |= (boot_arg_value ? kPEICanHasAssertions : 0);
68 
69 	if (!PE_parse_boot_argn("statistics", &boot_arg_value, sizeof(boot_arg_value))) {
70 #if DEVELOPMENT || DEBUG
71 		boot_arg_value = TRUE;
72 #else
73 		boot_arg_value = FALSE;
74 #endif
75 	}
76 	gPEKernelConfigurationBitmask |= (boot_arg_value ? kPEICanHasStatistics : 0);
77 
78 #if SECURE_KERNEL
79 	boot_arg_value = FALSE;
80 #else
81 	if (!PE_i_can_has_debugger(NULL)) {
82 		boot_arg_value = FALSE;
83 	} else if (!PE_parse_boot_argn("diagnostic_api", &boot_arg_value, sizeof(boot_arg_value))) {
84 		boot_arg_value = TRUE;
85 	}
86 #endif
87 	gPEKernelConfigurationBitmask |= (boot_arg_value ? kPEICanHasDiagnosticAPI : 0);
88 
89 
90 	int factor = 1;
91 	boolean_t have_bootarg = PE_parse_boot_argn("cpu-factor", &factor, sizeof(factor));
92 	if (have_bootarg) {
93 		debug_cpu_performance_degradation_factor = factor;
94 	} else {
95 		DTEntry         root;
96 		if (SecureDTLookupEntry(NULL, "/", &root) == kSuccess) {
97 			void const *prop = NULL;
98 			uint32_t size = 0;
99 			if (SecureDTGetProperty(root, "target-is-fpga", &prop, &size) == kSuccess) {
100 				debug_cpu_performance_degradation_factor = 10;
101 			}
102 		}
103 	}
104 }
105 
106 void
PE_enter_debugger(const char * cause)107 PE_enter_debugger(const char *cause)
108 {
109 	if (debug_boot_arg & DB_NMI) {
110 		Debugger(cause);
111 	}
112 }
113 
114 uint32_t
PE_i_can_has_kernel_configuration(void)115 PE_i_can_has_kernel_configuration(void)
116 {
117 	return gPEKernelConfigurationBitmask;
118 }
119 
120 /* extern references */
121 extern void vcattach(void);
122 
123 /* Globals */
124 typedef void (*PE_putc_t)(char);
125 
126 #if XNU_TARGET_OS_OSX
127 PE_putc_t PE_putc;
128 #else
129 SECURITY_READ_ONLY_LATE(PE_putc_t) PE_putc;
130 #endif
131 
132 extern void console_write_char(char);
133 
134 void
PE_init_printf(boolean_t vm_initialized)135 PE_init_printf(boolean_t vm_initialized)
136 {
137 	if (!vm_initialized) {
138 		PE_putc = console_write_char;
139 	} else {
140 		vcattach();
141 	}
142 }
143 
144 uint32_t
PE_get_random_seed(unsigned char * dst_random_seed,uint32_t request_size)145 PE_get_random_seed(unsigned char *dst_random_seed, uint32_t request_size)
146 {
147 	uint32_t        size = 0;
148 	uint8_t         *random_seed;
149 
150 #if CONFIG_SPTM
151 	char const prefix[] = "randseed";
152 	size_t const prefix_len = sizeof(prefix) - 1;
153 
154 	extern const sptm_bootstrap_args_xnu_t *SPTMArgs;
155 
156 #pragma clang diagnostic push
157 #pragma clang diagnostic ignored "-Wcast-qual"
158 	/* Legal, because we are not locked down yet. */
159 	random_seed = (uint8_t*)&SPTMArgs->random_seed;
160 #pragma GCC diagnostic pop
161 
162 	size = (uint32_t)SPTMArgs->random_seed_length;
163 
164 	if (size < prefix_len) {
165 		panic("random seed field too short");
166 	}
167 
168 	if (memcmp(random_seed, prefix, prefix_len) != 0) {
169 		panic("random seed corrupted");
170 	}
171 
172 	random_seed += prefix_len;
173 	size -= prefix_len;
174 #else /* CONFIG_SPTM */
175 	DTEntry         entryP;
176 
177 	if ((SecureDTLookupEntry(NULL, "/chosen", &entryP) != kSuccess)
178 	    || (SecureDTGetProperty(entryP, "random-seed",
179 	    /* casting away the const is permissible here, since
180 	     * this function runs before lockdown. */
181 	    (const void **)(uintptr_t)&random_seed, &size) != kSuccess)) {
182 		random_seed = NULL;
183 		size = 0;
184 	}
185 #endif /* CONFIG_SPTM */
186 
187 	if (random_seed == NULL || size == 0) {
188 		panic("no random seed");
189 	}
190 
191 	unsigned char *src_random_seed;
192 	unsigned int i;
193 	unsigned int null_count = 0;
194 
195 	src_random_seed = (unsigned char *)random_seed;
196 
197 	if (size > request_size) {
198 		size = request_size;
199 	}
200 
201 	/*
202 	 * Copy from the device tree into the destination buffer,
203 	 * count the number of null bytes and null out the device tree.
204 	 */
205 	for (i = 0; i < size; i++, src_random_seed++, dst_random_seed++) {
206 		*dst_random_seed = *src_random_seed;
207 		null_count += *src_random_seed == (unsigned char)0;
208 		*src_random_seed = (unsigned char)0;
209 	}
210 	if (null_count == size) {
211 		/* All nulls is no seed - return 0 */
212 		size = 0;
213 	}
214 
215 	return size;
216 }
217 
218 unsigned char appleClut8[256 * 3] = {
219 // 00
220 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0x66,
221 	0xFF, 0xFF, 0x33, 0xFF, 0xFF, 0x00, 0xFF, 0xCC, 0xFF, 0xFF, 0xCC, 0xCC,
222 	0xFF, 0xCC, 0x99, 0xFF, 0xCC, 0x66, 0xFF, 0xCC, 0x33, 0xFF, 0xCC, 0x00,
223 	0xFF, 0x99, 0xFF, 0xFF, 0x99, 0xCC, 0xFF, 0x99, 0x99, 0xFF, 0x99, 0x66,
224 // 10
225 	0xFF, 0x99, 0x33, 0xFF, 0x99, 0x00, 0xFF, 0x66, 0xFF, 0xFF, 0x66, 0xCC,
226 	0xFF, 0x66, 0x99, 0xFF, 0x66, 0x66, 0xFF, 0x66, 0x33, 0xFF, 0x66, 0x00,
227 	0xFF, 0x33, 0xFF, 0xFF, 0x33, 0xCC, 0xFF, 0x33, 0x99, 0xFF, 0x33, 0x66,
228 	0xFF, 0x33, 0x33, 0xFF, 0x33, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xCC,
229 // 20
230 	0xFF, 0x00, 0x99, 0xFF, 0x00, 0x66, 0xFF, 0x00, 0x33, 0xFF, 0x00, 0x00,
231 	0xCC, 0xFF, 0xFF, 0xCC, 0xFF, 0xCC, 0xCC, 0xFF, 0x99, 0xCC, 0xFF, 0x66,
232 	0xCC, 0xFF, 0x33, 0xCC, 0xFF, 0x00, 0xCC, 0xCC, 0xFF, 0xCC, 0xCC, 0xCC,
233 	0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x33, 0xCC, 0xCC, 0x00,
234 // 30
235 	0xCC, 0x99, 0xFF, 0xCC, 0x99, 0xCC, 0xCC, 0x99, 0x99, 0xCC, 0x99, 0x66,
236 	0xCC, 0x99, 0x33, 0xCC, 0x99, 0x00, 0xCC, 0x66, 0xFF, 0xCC, 0x66, 0xCC,
237 	0xCC, 0x66, 0x99, 0xCC, 0x66, 0x66, 0xCC, 0x66, 0x33, 0xCC, 0x66, 0x00,
238 	0xCC, 0x33, 0xFF, 0xCC, 0x33, 0xCC, 0xCC, 0x33, 0x99, 0xCC, 0x33, 0x66,
239 // 40
240 	0xCC, 0x33, 0x33, 0xCC, 0x33, 0x00, 0xCC, 0x00, 0xFF, 0xCC, 0x00, 0xCC,
241 	0xCC, 0x00, 0x99, 0xCC, 0x00, 0x66, 0xCC, 0x00, 0x33, 0xCC, 0x00, 0x00,
242 	0x99, 0xFF, 0xFF, 0x99, 0xFF, 0xCC, 0x99, 0xFF, 0x99, 0x99, 0xFF, 0x66,
243 	0x99, 0xFF, 0x33, 0x99, 0xFF, 0x00, 0x99, 0xCC, 0xFF, 0x99, 0xCC, 0xCC,
244 // 50
245 	0x99, 0xCC, 0x99, 0x99, 0xCC, 0x66, 0x99, 0xCC, 0x33, 0x99, 0xCC, 0x00,
246 	0x99, 0x99, 0xFF, 0x99, 0x99, 0xCC, 0x99, 0x99, 0x99, 0x99, 0x99, 0x66,
247 	0x99, 0x99, 0x33, 0x99, 0x99, 0x00, 0x99, 0x66, 0xFF, 0x99, 0x66, 0xCC,
248 	0x99, 0x66, 0x99, 0x99, 0x66, 0x66, 0x99, 0x66, 0x33, 0x99, 0x66, 0x00,
249 // 60
250 	0x99, 0x33, 0xFF, 0x99, 0x33, 0xCC, 0x99, 0x33, 0x99, 0x99, 0x33, 0x66,
251 	0x99, 0x33, 0x33, 0x99, 0x33, 0x00, 0x99, 0x00, 0xFF, 0x99, 0x00, 0xCC,
252 	0x99, 0x00, 0x99, 0x99, 0x00, 0x66, 0x99, 0x00, 0x33, 0x99, 0x00, 0x00,
253 	0x66, 0xFF, 0xFF, 0x66, 0xFF, 0xCC, 0x66, 0xFF, 0x99, 0x66, 0xFF, 0x66,
254 // 70
255 	0x66, 0xFF, 0x33, 0x66, 0xFF, 0x00, 0x66, 0xCC, 0xFF, 0x66, 0xCC, 0xCC,
256 	0x66, 0xCC, 0x99, 0x66, 0xCC, 0x66, 0x66, 0xCC, 0x33, 0x66, 0xCC, 0x00,
257 	0x66, 0x99, 0xFF, 0x66, 0x99, 0xCC, 0x66, 0x99, 0x99, 0x66, 0x99, 0x66,
258 	0x66, 0x99, 0x33, 0x66, 0x99, 0x00, 0x66, 0x66, 0xFF, 0x66, 0x66, 0xCC,
259 // 80
260 	0x66, 0x66, 0x99, 0x66, 0x66, 0x66, 0x66, 0x66, 0x33, 0x66, 0x66, 0x00,
261 	0x66, 0x33, 0xFF, 0x66, 0x33, 0xCC, 0x66, 0x33, 0x99, 0x66, 0x33, 0x66,
262 	0x66, 0x33, 0x33, 0x66, 0x33, 0x00, 0x66, 0x00, 0xFF, 0x66, 0x00, 0xCC,
263 	0x66, 0x00, 0x99, 0x66, 0x00, 0x66, 0x66, 0x00, 0x33, 0x66, 0x00, 0x00,
264 // 90
265 	0x33, 0xFF, 0xFF, 0x33, 0xFF, 0xCC, 0x33, 0xFF, 0x99, 0x33, 0xFF, 0x66,
266 	0x33, 0xFF, 0x33, 0x33, 0xFF, 0x00, 0x33, 0xCC, 0xFF, 0x33, 0xCC, 0xCC,
267 	0x33, 0xCC, 0x99, 0x33, 0xCC, 0x66, 0x33, 0xCC, 0x33, 0x33, 0xCC, 0x00,
268 	0x33, 0x99, 0xFF, 0x33, 0x99, 0xCC, 0x33, 0x99, 0x99, 0x33, 0x99, 0x66,
269 // a0
270 	0x33, 0x99, 0x33, 0x33, 0x99, 0x00, 0x33, 0x66, 0xFF, 0x33, 0x66, 0xCC,
271 	0x33, 0x66, 0x99, 0x33, 0x66, 0x66, 0x33, 0x66, 0x33, 0x33, 0x66, 0x00,
272 	0x33, 0x33, 0xFF, 0x33, 0x33, 0xCC, 0x33, 0x33, 0x99, 0x33, 0x33, 0x66,
273 	0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x33, 0x00, 0xFF, 0x33, 0x00, 0xCC,
274 // b0
275 	0x33, 0x00, 0x99, 0x33, 0x00, 0x66, 0x33, 0x00, 0x33, 0x33, 0x00, 0x00,
276 	0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xCC, 0x00, 0xFF, 0x99, 0x00, 0xFF, 0x66,
277 	0x00, 0xFF, 0x33, 0x00, 0xFF, 0x00, 0x00, 0xCC, 0xFF, 0x00, 0xCC, 0xCC,
278 	0x00, 0xCC, 0x99, 0x00, 0xCC, 0x66, 0x00, 0xCC, 0x33, 0x00, 0xCC, 0x00,
279 // c0
280 	0x00, 0x99, 0xFF, 0x00, 0x99, 0xCC, 0x00, 0x99, 0x99, 0x00, 0x99, 0x66,
281 	0x00, 0x99, 0x33, 0x00, 0x99, 0x00, 0x00, 0x66, 0xFF, 0x00, 0x66, 0xCC,
282 	0x00, 0x66, 0x99, 0x00, 0x66, 0x66, 0x00, 0x66, 0x33, 0x00, 0x66, 0x00,
283 	0x00, 0x33, 0xFF, 0x00, 0x33, 0xCC, 0x00, 0x33, 0x99, 0x00, 0x33, 0x66,
284 // d0
285 	0x00, 0x33, 0x33, 0x00, 0x33, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xCC,
286 	0x00, 0x00, 0x99, 0x00, 0x00, 0x66, 0x00, 0x00, 0x33, 0xEE, 0x00, 0x00,
287 	0xDD, 0x00, 0x00, 0xBB, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x88, 0x00, 0x00,
288 	0x77, 0x00, 0x00, 0x55, 0x00, 0x00, 0x44, 0x00, 0x00, 0x22, 0x00, 0x00,
289 // e0
290 	0x11, 0x00, 0x00, 0x00, 0xEE, 0x00, 0x00, 0xDD, 0x00, 0x00, 0xBB, 0x00,
291 	0x00, 0xAA, 0x00, 0x00, 0x88, 0x00, 0x00, 0x77, 0x00, 0x00, 0x55, 0x00,
292 	0x00, 0x44, 0x00, 0x00, 0x22, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xEE,
293 	0x00, 0x00, 0xDD, 0x00, 0x00, 0xBB, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x88,
294 // f0
295 	0x00, 0x00, 0x77, 0x00, 0x00, 0x55, 0x00, 0x00, 0x44, 0x00, 0x00, 0x22,
296 	0x00, 0x00, 0x11, 0xEE, 0xEE, 0xEE, 0xDD, 0xDD, 0xDD, 0xBB, 0xBB, 0xBB,
297 	0xAA, 0xAA, 0xAA, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x55, 0x55, 0x55,
298 	0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00
299 };
300