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
40 #if defined(__arm64__)
41 SECURITY_READ_ONLY_LATE(static uint32_t) gPEKernelConfigurationBitmask;
42 #else
43 static uint32_t gPEKernelConfigurationBitmask;
44 #endif
45
46 int32_t gPESerialBaud = -1;
47
48 int debug_cpu_performance_degradation_factor = 1;
49
50 void
pe_init_debug(void)51 pe_init_debug(void)
52 {
53 boolean_t boot_arg_value;
54
55 gPEKernelConfigurationBitmask = 0;
56
57 if (!PE_parse_boot_argn("assertions", &boot_arg_value, sizeof(boot_arg_value))) {
58 #if MACH_ASSERT
59 boot_arg_value = TRUE;
60 #else
61 boot_arg_value = FALSE;
62 #endif
63 }
64 gPEKernelConfigurationBitmask |= (boot_arg_value ? kPEICanHasAssertions : 0);
65
66 if (!PE_parse_boot_argn("statistics", &boot_arg_value, sizeof(boot_arg_value))) {
67 #if DEVELOPMENT || DEBUG
68 boot_arg_value = TRUE;
69 #else
70 boot_arg_value = FALSE;
71 #endif
72 }
73 gPEKernelConfigurationBitmask |= (boot_arg_value ? kPEICanHasStatistics : 0);
74
75 #if SECURE_KERNEL
76 boot_arg_value = FALSE;
77 #else
78 if (!PE_i_can_has_debugger(NULL)) {
79 boot_arg_value = FALSE;
80 } else if (!PE_parse_boot_argn("diagnostic_api", &boot_arg_value, sizeof(boot_arg_value))) {
81 boot_arg_value = TRUE;
82 }
83 #endif
84 gPEKernelConfigurationBitmask |= (boot_arg_value ? kPEICanHasDiagnosticAPI : 0);
85
86
87 int factor = 1;
88 boolean_t have_bootarg = PE_parse_boot_argn("cpu-factor", &factor, sizeof(factor));
89 if (have_bootarg) {
90 debug_cpu_performance_degradation_factor = factor;
91 } else {
92 DTEntry root;
93 if (SecureDTLookupEntry(NULL, "/", &root) == kSuccess) {
94 void const *prop = NULL;
95 uint32_t size = 0;
96 if (SecureDTGetProperty(root, "target-is-fpga", &prop, &size) == kSuccess) {
97 debug_cpu_performance_degradation_factor = 10;
98 }
99 }
100 }
101 }
102
103 void
PE_enter_debugger(const char * cause)104 PE_enter_debugger(const char *cause)
105 {
106 if (debug_boot_arg & DB_NMI) {
107 Debugger(cause);
108 }
109 }
110
111 uint32_t
PE_i_can_has_kernel_configuration(void)112 PE_i_can_has_kernel_configuration(void)
113 {
114 return gPEKernelConfigurationBitmask;
115 }
116
117 /* extern references */
118 extern void vcattach(void);
119
120 /* Globals */
121 typedef void (*PE_putc_t)(char);
122
123 #if XNU_TARGET_OS_OSX
124 PE_putc_t PE_putc;
125 #else
126 SECURITY_READ_ONLY_LATE(PE_putc_t) PE_putc;
127 #endif
128
129 extern void console_write_char(char);
130
131 void
PE_init_printf(boolean_t vm_initialized)132 PE_init_printf(boolean_t vm_initialized)
133 {
134 if (!vm_initialized) {
135 PE_putc = console_write_char;
136 } else {
137 vcattach();
138 }
139 }
140
141 uint32_t
PE_get_random_seed(unsigned char * dst_random_seed,uint32_t request_size)142 PE_get_random_seed(unsigned char *dst_random_seed, uint32_t request_size)
143 {
144 uint32_t size = 0;
145 uint8_t *random_seed;
146
147 DTEntry entryP;
148
149 if ((SecureDTLookupEntry(NULL, "/chosen", &entryP) != kSuccess)
150 || (SecureDTGetProperty(entryP, "random-seed",
151 /* casting away the const is permissible here, since
152 * this function runs before lockdown. */
153 (const void **)(uintptr_t)&random_seed, &size) != kSuccess)) {
154 random_seed = NULL;
155 size = 0;
156 }
157
158 if (random_seed == NULL || size == 0) {
159 panic("no random seed");
160 }
161
162 unsigned char *src_random_seed;
163 unsigned int i;
164 unsigned int null_count = 0;
165
166 src_random_seed = (unsigned char *)random_seed;
167
168 if (size > request_size) {
169 size = request_size;
170 }
171
172 /*
173 * Copy from the device tree into the destination buffer,
174 * count the number of null bytes and null out the device tree.
175 */
176 for (i = 0; i < size; i++, src_random_seed++, dst_random_seed++) {
177 *dst_random_seed = *src_random_seed;
178 null_count += *src_random_seed == (unsigned char)0;
179 *src_random_seed = (unsigned char)0;
180 }
181 if (null_count == size) {
182 /* All nulls is no seed - return 0 */
183 size = 0;
184 }
185
186 return size;
187 }
188
189 unsigned char appleClut8[256 * 3] = {
190 // 00
191 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0x66,
192 0xFF, 0xFF, 0x33, 0xFF, 0xFF, 0x00, 0xFF, 0xCC, 0xFF, 0xFF, 0xCC, 0xCC,
193 0xFF, 0xCC, 0x99, 0xFF, 0xCC, 0x66, 0xFF, 0xCC, 0x33, 0xFF, 0xCC, 0x00,
194 0xFF, 0x99, 0xFF, 0xFF, 0x99, 0xCC, 0xFF, 0x99, 0x99, 0xFF, 0x99, 0x66,
195 // 10
196 0xFF, 0x99, 0x33, 0xFF, 0x99, 0x00, 0xFF, 0x66, 0xFF, 0xFF, 0x66, 0xCC,
197 0xFF, 0x66, 0x99, 0xFF, 0x66, 0x66, 0xFF, 0x66, 0x33, 0xFF, 0x66, 0x00,
198 0xFF, 0x33, 0xFF, 0xFF, 0x33, 0xCC, 0xFF, 0x33, 0x99, 0xFF, 0x33, 0x66,
199 0xFF, 0x33, 0x33, 0xFF, 0x33, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xCC,
200 // 20
201 0xFF, 0x00, 0x99, 0xFF, 0x00, 0x66, 0xFF, 0x00, 0x33, 0xFF, 0x00, 0x00,
202 0xCC, 0xFF, 0xFF, 0xCC, 0xFF, 0xCC, 0xCC, 0xFF, 0x99, 0xCC, 0xFF, 0x66,
203 0xCC, 0xFF, 0x33, 0xCC, 0xFF, 0x00, 0xCC, 0xCC, 0xFF, 0xCC, 0xCC, 0xCC,
204 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x33, 0xCC, 0xCC, 0x00,
205 // 30
206 0xCC, 0x99, 0xFF, 0xCC, 0x99, 0xCC, 0xCC, 0x99, 0x99, 0xCC, 0x99, 0x66,
207 0xCC, 0x99, 0x33, 0xCC, 0x99, 0x00, 0xCC, 0x66, 0xFF, 0xCC, 0x66, 0xCC,
208 0xCC, 0x66, 0x99, 0xCC, 0x66, 0x66, 0xCC, 0x66, 0x33, 0xCC, 0x66, 0x00,
209 0xCC, 0x33, 0xFF, 0xCC, 0x33, 0xCC, 0xCC, 0x33, 0x99, 0xCC, 0x33, 0x66,
210 // 40
211 0xCC, 0x33, 0x33, 0xCC, 0x33, 0x00, 0xCC, 0x00, 0xFF, 0xCC, 0x00, 0xCC,
212 0xCC, 0x00, 0x99, 0xCC, 0x00, 0x66, 0xCC, 0x00, 0x33, 0xCC, 0x00, 0x00,
213 0x99, 0xFF, 0xFF, 0x99, 0xFF, 0xCC, 0x99, 0xFF, 0x99, 0x99, 0xFF, 0x66,
214 0x99, 0xFF, 0x33, 0x99, 0xFF, 0x00, 0x99, 0xCC, 0xFF, 0x99, 0xCC, 0xCC,
215 // 50
216 0x99, 0xCC, 0x99, 0x99, 0xCC, 0x66, 0x99, 0xCC, 0x33, 0x99, 0xCC, 0x00,
217 0x99, 0x99, 0xFF, 0x99, 0x99, 0xCC, 0x99, 0x99, 0x99, 0x99, 0x99, 0x66,
218 0x99, 0x99, 0x33, 0x99, 0x99, 0x00, 0x99, 0x66, 0xFF, 0x99, 0x66, 0xCC,
219 0x99, 0x66, 0x99, 0x99, 0x66, 0x66, 0x99, 0x66, 0x33, 0x99, 0x66, 0x00,
220 // 60
221 0x99, 0x33, 0xFF, 0x99, 0x33, 0xCC, 0x99, 0x33, 0x99, 0x99, 0x33, 0x66,
222 0x99, 0x33, 0x33, 0x99, 0x33, 0x00, 0x99, 0x00, 0xFF, 0x99, 0x00, 0xCC,
223 0x99, 0x00, 0x99, 0x99, 0x00, 0x66, 0x99, 0x00, 0x33, 0x99, 0x00, 0x00,
224 0x66, 0xFF, 0xFF, 0x66, 0xFF, 0xCC, 0x66, 0xFF, 0x99, 0x66, 0xFF, 0x66,
225 // 70
226 0x66, 0xFF, 0x33, 0x66, 0xFF, 0x00, 0x66, 0xCC, 0xFF, 0x66, 0xCC, 0xCC,
227 0x66, 0xCC, 0x99, 0x66, 0xCC, 0x66, 0x66, 0xCC, 0x33, 0x66, 0xCC, 0x00,
228 0x66, 0x99, 0xFF, 0x66, 0x99, 0xCC, 0x66, 0x99, 0x99, 0x66, 0x99, 0x66,
229 0x66, 0x99, 0x33, 0x66, 0x99, 0x00, 0x66, 0x66, 0xFF, 0x66, 0x66, 0xCC,
230 // 80
231 0x66, 0x66, 0x99, 0x66, 0x66, 0x66, 0x66, 0x66, 0x33, 0x66, 0x66, 0x00,
232 0x66, 0x33, 0xFF, 0x66, 0x33, 0xCC, 0x66, 0x33, 0x99, 0x66, 0x33, 0x66,
233 0x66, 0x33, 0x33, 0x66, 0x33, 0x00, 0x66, 0x00, 0xFF, 0x66, 0x00, 0xCC,
234 0x66, 0x00, 0x99, 0x66, 0x00, 0x66, 0x66, 0x00, 0x33, 0x66, 0x00, 0x00,
235 // 90
236 0x33, 0xFF, 0xFF, 0x33, 0xFF, 0xCC, 0x33, 0xFF, 0x99, 0x33, 0xFF, 0x66,
237 0x33, 0xFF, 0x33, 0x33, 0xFF, 0x00, 0x33, 0xCC, 0xFF, 0x33, 0xCC, 0xCC,
238 0x33, 0xCC, 0x99, 0x33, 0xCC, 0x66, 0x33, 0xCC, 0x33, 0x33, 0xCC, 0x00,
239 0x33, 0x99, 0xFF, 0x33, 0x99, 0xCC, 0x33, 0x99, 0x99, 0x33, 0x99, 0x66,
240 // a0
241 0x33, 0x99, 0x33, 0x33, 0x99, 0x00, 0x33, 0x66, 0xFF, 0x33, 0x66, 0xCC,
242 0x33, 0x66, 0x99, 0x33, 0x66, 0x66, 0x33, 0x66, 0x33, 0x33, 0x66, 0x00,
243 0x33, 0x33, 0xFF, 0x33, 0x33, 0xCC, 0x33, 0x33, 0x99, 0x33, 0x33, 0x66,
244 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x33, 0x00, 0xFF, 0x33, 0x00, 0xCC,
245 // b0
246 0x33, 0x00, 0x99, 0x33, 0x00, 0x66, 0x33, 0x00, 0x33, 0x33, 0x00, 0x00,
247 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xCC, 0x00, 0xFF, 0x99, 0x00, 0xFF, 0x66,
248 0x00, 0xFF, 0x33, 0x00, 0xFF, 0x00, 0x00, 0xCC, 0xFF, 0x00, 0xCC, 0xCC,
249 0x00, 0xCC, 0x99, 0x00, 0xCC, 0x66, 0x00, 0xCC, 0x33, 0x00, 0xCC, 0x00,
250 // c0
251 0x00, 0x99, 0xFF, 0x00, 0x99, 0xCC, 0x00, 0x99, 0x99, 0x00, 0x99, 0x66,
252 0x00, 0x99, 0x33, 0x00, 0x99, 0x00, 0x00, 0x66, 0xFF, 0x00, 0x66, 0xCC,
253 0x00, 0x66, 0x99, 0x00, 0x66, 0x66, 0x00, 0x66, 0x33, 0x00, 0x66, 0x00,
254 0x00, 0x33, 0xFF, 0x00, 0x33, 0xCC, 0x00, 0x33, 0x99, 0x00, 0x33, 0x66,
255 // d0
256 0x00, 0x33, 0x33, 0x00, 0x33, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xCC,
257 0x00, 0x00, 0x99, 0x00, 0x00, 0x66, 0x00, 0x00, 0x33, 0xEE, 0x00, 0x00,
258 0xDD, 0x00, 0x00, 0xBB, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x88, 0x00, 0x00,
259 0x77, 0x00, 0x00, 0x55, 0x00, 0x00, 0x44, 0x00, 0x00, 0x22, 0x00, 0x00,
260 // e0
261 0x11, 0x00, 0x00, 0x00, 0xEE, 0x00, 0x00, 0xDD, 0x00, 0x00, 0xBB, 0x00,
262 0x00, 0xAA, 0x00, 0x00, 0x88, 0x00, 0x00, 0x77, 0x00, 0x00, 0x55, 0x00,
263 0x00, 0x44, 0x00, 0x00, 0x22, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xEE,
264 0x00, 0x00, 0xDD, 0x00, 0x00, 0xBB, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x88,
265 // f0
266 0x00, 0x00, 0x77, 0x00, 0x00, 0x55, 0x00, 0x00, 0x44, 0x00, 0x00, 0x22,
267 0x00, 0x00, 0x11, 0xEE, 0xEE, 0xEE, 0xDD, 0xDD, 0xDD, 0xBB, 0xBB, 0xBB,
268 0xAA, 0xAA, 0xAA, 0x88, 0x88, 0x88, 0x77, 0x77, 0x77, 0x55, 0x55, 0x55,
269 0x44, 0x44, 0x44, 0x22, 0x22, 0x22, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00
270 };
271