]>
Commit | Line | Data |
---|---|---|
b0d623f7 | 1 | /* |
39037602 | 2 | * Copyright (c) 2008-2016 Apple Inc. All rights reserved. |
b0d623f7 A |
3 | * |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ | |
0a7de745 | 5 | * |
b0d623f7 A |
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. | |
0a7de745 | 14 | * |
b0d623f7 A |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
0a7de745 | 17 | * |
b0d623f7 A |
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. | |
0a7de745 | 25 | * |
b0d623f7 A |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
27 | */ | |
28 | ||
39236c6e A |
29 | #include <sys/errno.h> |
30 | ||
b0d623f7 A |
31 | #include <mach/mach_types.h> |
32 | #include <mach/vm_attributes.h> | |
33 | #include <mach/vm_param.h> | |
34 | #include <libsa/types.h> | |
35 | ||
36 | #include <vm/vm_map.h> | |
37 | #include <i386/pmap.h> | |
316670eb | 38 | #include <i386/pmap_internal.h> /* pmap_pde */ |
b0d623f7 A |
39 | #include <i386/mp.h> |
40 | #include <i386/misc_protos.h> | |
41 | #include <i386/pio.h> | |
42 | #include <i386/proc_reg.h> | |
43 | ||
7ddcb079 A |
44 | #include <i386/pmap_internal.h> |
45 | ||
b0d623f7 | 46 | #include <kdp/kdp_internal.h> |
316670eb A |
47 | #include <kdp/kdp_core.h> |
48 | #include <kdp/ml/i386/kdp_x86_common.h> | |
b0d623f7 A |
49 | #include <mach/vm_map.h> |
50 | ||
51 | #include <vm/vm_protos.h> | |
52 | #include <vm/vm_kern.h> | |
53 | ||
6d2010ae | 54 | #include <machine/pal_routines.h> |
316670eb | 55 | #include <libkern/kernel_mach_header.h> |
6d2010ae | 56 | |
b0d623f7 A |
57 | // #define KDP_VM_READ_DEBUG 1 |
58 | // #define KDP_VM_WRITE_DEBUG 1 | |
59 | ||
39236c6e A |
60 | /* |
61 | * A (potentially valid) physical address is not a kernel address | |
62 | * i.e. it'a a user address. | |
63 | */ | |
0a7de745 | 64 | #define IS_PHYS_ADDR(addr) IS_USERADDR64_CANONICAL(addr) |
39236c6e | 65 | |
b0d623f7 A |
66 | boolean_t kdp_read_io; |
67 | boolean_t kdp_trans_off; | |
68 | ||
39037602 | 69 | pmap_paddr_t kdp_vtophys(pmap_t pmap, vm_offset_t va); |
b0d623f7 A |
70 | |
71 | pmap_t kdp_pmap = 0; | |
72 | ||
0a7de745 A |
73 | kdp_jtag_coredump_t kdp_jtag_coredump; |
74 | ||
39037602 | 75 | pmap_paddr_t |
b0d623f7 A |
76 | kdp_vtophys( |
77 | pmap_t pmap, | |
39037602 | 78 | vm_offset_t va) |
b0d623f7 | 79 | { |
39037602 | 80 | pmap_paddr_t pa; |
b0d623f7 A |
81 | ppnum_t pp; |
82 | ||
83 | pp = pmap_find_phys(pmap, va); | |
0a7de745 A |
84 | if (!pp) { |
85 | return 0; | |
86 | } | |
87 | ||
39037602 | 88 | pa = ((pmap_paddr_t)pp << PAGE_SHIFT) | (va & PAGE_MASK); |
b0d623f7 | 89 | |
0a7de745 | 90 | return pa; |
b0d623f7 A |
91 | } |
92 | ||
93 | mach_vm_size_t | |
94 | kdp_machine_vm_read( mach_vm_address_t src, caddr_t dst, mach_vm_size_t len) | |
95 | { | |
6d2010ae A |
96 | addr64_t cur_virt_src = PAL_KDP_ADDR((addr64_t)src); |
97 | addr64_t cur_virt_dst = PAL_KDP_ADDR((addr64_t)(intptr_t)dst); | |
b0d623f7 A |
98 | addr64_t cur_phys_dst, cur_phys_src; |
99 | mach_vm_size_t resid = len; | |
100 | mach_vm_size_t cnt = 0, cnt_src, cnt_dst; | |
101 | pmap_t src_pmap = kernel_pmap; | |
102 | ||
103 | #ifdef KDP_VM_READ_DEBUG | |
104 | printf("kdp_vm_read: src %llx dst %p len %llx\n", src, (void *)dst, len); | |
105 | #endif | |
106 | ||
39236c6e | 107 | if (kdp_trans_off && IS_PHYS_ADDR(src)) { |
b0d623f7 A |
108 | kdp_readphysmem64_req_t rq; |
109 | mach_vm_size_t ret; | |
110 | ||
111 | rq.address = src; | |
112 | rq.nbytes = (uint32_t)len; | |
113 | ret = kdp_machine_phys_read(&rq, dst, KDP_CURRENT_LCPU); | |
114 | return ret; | |
115 | } | |
116 | ||
117 | /* If a different pmap has been specified with kdp_pmap, use it to translate the | |
118 | * source (cur_virt_src); otherwise, the source is translated using the | |
119 | * kernel_pmap. | |
120 | */ | |
0a7de745 | 121 | if (kdp_pmap) { |
b0d623f7 | 122 | src_pmap = kdp_pmap; |
0a7de745 | 123 | } |
b0d623f7 A |
124 | |
125 | while (resid != 0) { | |
126 | if (!(cur_phys_src = kdp_vtophys(src_pmap, | |
0a7de745 | 127 | cur_virt_src))) { |
b0d623f7 | 128 | goto exit; |
0a7de745 | 129 | } |
b0d623f7 A |
130 | |
131 | /* Always translate the destination buffer using the kernel_pmap */ | |
0a7de745 | 132 | if (!(cur_phys_dst = kdp_vtophys(kernel_pmap, cur_virt_dst))) { |
b0d623f7 | 133 | goto exit; |
0a7de745 | 134 | } |
b0d623f7 A |
135 | |
136 | /* Validate physical page numbers unless kdp_read_io is set */ | |
0a7de745 A |
137 | if (kdp_read_io == FALSE) { |
138 | if (!pmap_valid_page(i386_btop(cur_phys_dst)) || !pmap_valid_page(i386_btop(cur_phys_src))) { | |
b0d623f7 | 139 | goto exit; |
0a7de745 A |
140 | } |
141 | } | |
b0d623f7 A |
142 | |
143 | /* Get length left on page */ | |
144 | cnt_src = PAGE_SIZE - (cur_phys_src & PAGE_MASK); | |
145 | cnt_dst = PAGE_SIZE - (cur_phys_dst & PAGE_MASK); | |
0a7de745 | 146 | if (cnt_src > cnt_dst) { |
b0d623f7 | 147 | cnt = cnt_dst; |
0a7de745 | 148 | } else { |
b0d623f7 | 149 | cnt = cnt_src; |
0a7de745 A |
150 | } |
151 | if (cnt > resid) { | |
b0d623f7 | 152 | cnt = resid; |
0a7de745 | 153 | } |
b0d623f7 A |
154 | |
155 | /* Do a physical copy */ | |
39236c6e | 156 | if (EFAULT == ml_copy_phys(cur_phys_src, |
0a7de745 A |
157 | cur_phys_dst, |
158 | (vm_size_t)cnt)) { | |
39236c6e | 159 | goto exit; |
0a7de745 | 160 | } |
b0d623f7 A |
161 | cur_virt_src += cnt; |
162 | cur_virt_dst += cnt; | |
163 | resid -= cnt; | |
164 | } | |
165 | exit: | |
0a7de745 | 166 | return len - resid; |
b0d623f7 A |
167 | } |
168 | ||
169 | mach_vm_size_t | |
170 | kdp_machine_phys_read(kdp_readphysmem64_req_t *rq, caddr_t dst, | |
0a7de745 | 171 | uint16_t lcpu) |
b0d623f7 A |
172 | { |
173 | mach_vm_address_t src = rq->address; | |
174 | mach_vm_size_t len = rq->nbytes; | |
0a7de745 | 175 | |
b0d623f7 A |
176 | addr64_t cur_virt_dst; |
177 | addr64_t cur_phys_dst, cur_phys_src; | |
178 | mach_vm_size_t resid = len; | |
179 | mach_vm_size_t cnt = 0, cnt_src, cnt_dst; | |
180 | ||
0a7de745 A |
181 | if ((lcpu != KDP_CURRENT_LCPU) && (lcpu != cpu_number())) { |
182 | return (mach_vm_size_t) | |
183 | kdp_x86_xcpu_invoke(lcpu, (kdp_x86_xcpu_func_t)kdp_machine_phys_read, rq, dst); | |
184 | } | |
b0d623f7 A |
185 | |
186 | #ifdef KDP_VM_READ_DEBUG | |
187 | printf("kdp_phys_read: src %llx dst %p len %llx\n", src, (void *)dst, len); | |
188 | #endif | |
189 | ||
190 | cur_virt_dst = (addr64_t)(intptr_t)dst; | |
191 | cur_phys_src = (addr64_t)src; | |
192 | ||
193 | while (resid != 0) { | |
0a7de745 | 194 | if (!(cur_phys_dst = kdp_vtophys(kernel_pmap, cur_virt_dst))) { |
b0d623f7 | 195 | goto exit; |
0a7de745 | 196 | } |
b0d623f7 A |
197 | |
198 | /* Get length left on page */ | |
199 | cnt_src = PAGE_SIZE - (cur_phys_src & PAGE_MASK); | |
200 | cnt_dst = PAGE_SIZE - (cur_phys_dst & PAGE_MASK); | |
0a7de745 | 201 | if (cnt_src > cnt_dst) { |
b0d623f7 | 202 | cnt = cnt_dst; |
0a7de745 | 203 | } else { |
b0d623f7 | 204 | cnt = cnt_src; |
0a7de745 A |
205 | } |
206 | if (cnt > resid) { | |
b0d623f7 | 207 | cnt = resid; |
0a7de745 | 208 | } |
b0d623f7 | 209 | |
0a7de745 A |
210 | /* Do a physical copy; use ml_copy_phys() in the event this is |
211 | * a short read with potential side effects. | |
212 | */ | |
39236c6e | 213 | if (EFAULT == ml_copy_phys(cur_phys_src, |
0a7de745 A |
214 | cur_phys_dst, |
215 | (vm_size_t)cnt)) { | |
39236c6e | 216 | goto exit; |
0a7de745 | 217 | } |
b0d623f7 A |
218 | cur_phys_src += cnt; |
219 | cur_virt_dst += cnt; | |
220 | resid -= cnt; | |
221 | } | |
222 | exit: | |
0a7de745 | 223 | return len - resid; |
b0d623f7 A |
224 | } |
225 | ||
226 | /* | |
0a7de745 | 227 | * |
b0d623f7 A |
228 | */ |
229 | mach_vm_size_t | |
230 | kdp_machine_vm_write( caddr_t src, mach_vm_address_t dst, mach_vm_size_t len) | |
0a7de745 | 231 | { |
b0d623f7 A |
232 | addr64_t cur_virt_src, cur_virt_dst; |
233 | addr64_t cur_phys_src, cur_phys_dst; | |
234 | unsigned resid, cnt, cnt_src, cnt_dst; | |
235 | ||
236 | #ifdef KDP_VM_WRITE_DEBUG | |
237 | printf("kdp_vm_write: src %p dst %llx len %llx - %08X %08X\n", (void *)src, dst, len, ((unsigned int *)src)[0], ((unsigned int *)src)[1]); | |
238 | #endif | |
239 | ||
6d2010ae A |
240 | cur_virt_src = PAL_KDP_ADDR((addr64_t)(intptr_t)src); |
241 | cur_virt_dst = PAL_KDP_ADDR((addr64_t)dst); | |
b0d623f7 A |
242 | |
243 | resid = (unsigned)len; | |
244 | ||
245 | while (resid != 0) { | |
0a7de745 | 246 | if ((cur_phys_dst = kdp_vtophys(kernel_pmap, cur_virt_dst)) == 0) { |
b0d623f7 | 247 | goto exit; |
0a7de745 | 248 | } |
b0d623f7 | 249 | |
0a7de745 | 250 | if ((cur_phys_src = kdp_vtophys(kernel_pmap, cur_virt_src)) == 0) { |
b0d623f7 | 251 | goto exit; |
0a7de745 | 252 | } |
b0d623f7 A |
253 | |
254 | /* Copy as many bytes as possible without crossing a page */ | |
255 | cnt_src = (unsigned)(PAGE_SIZE - (cur_phys_src & PAGE_MASK)); | |
256 | cnt_dst = (unsigned)(PAGE_SIZE - (cur_phys_dst & PAGE_MASK)); | |
257 | ||
0a7de745 | 258 | if (cnt_src > cnt_dst) { |
b0d623f7 | 259 | cnt = cnt_dst; |
0a7de745 | 260 | } else { |
b0d623f7 | 261 | cnt = cnt_src; |
0a7de745 A |
262 | } |
263 | if (cnt > resid) { | |
b0d623f7 | 264 | cnt = resid; |
0a7de745 | 265 | } |
b0d623f7 | 266 | |
0a7de745 A |
267 | if (EFAULT == ml_copy_phys(cur_phys_src, cur_phys_dst, cnt)) { |
268 | goto exit; /* Copy stuff over */ | |
269 | } | |
270 | cur_virt_src += cnt; | |
271 | cur_virt_dst += cnt; | |
b0d623f7 A |
272 | resid -= cnt; |
273 | } | |
274 | exit: | |
0a7de745 | 275 | return len - resid; |
b0d623f7 A |
276 | } |
277 | ||
278 | /* | |
0a7de745 | 279 | * |
b0d623f7 A |
280 | */ |
281 | mach_vm_size_t | |
282 | kdp_machine_phys_write(kdp_writephysmem64_req_t *rq, caddr_t src, | |
0a7de745 A |
283 | uint16_t lcpu) |
284 | { | |
b0d623f7 A |
285 | mach_vm_address_t dst = rq->address; |
286 | mach_vm_size_t len = rq->nbytes; | |
287 | addr64_t cur_virt_src; | |
288 | addr64_t cur_phys_src, cur_phys_dst; | |
289 | unsigned resid, cnt, cnt_src, cnt_dst; | |
290 | ||
0a7de745 A |
291 | if ((lcpu != KDP_CURRENT_LCPU) && (lcpu != cpu_number())) { |
292 | return (mach_vm_size_t) | |
293 | kdp_x86_xcpu_invoke(lcpu, (kdp_x86_xcpu_func_t)kdp_machine_phys_write, rq, src); | |
294 | } | |
b0d623f7 A |
295 | |
296 | #ifdef KDP_VM_WRITE_DEBUG | |
297 | printf("kdp_phys_write: src %p dst %llx len %llx - %08X %08X\n", (void *)src, dst, len, ((unsigned int *)src)[0], ((unsigned int *)src)[1]); | |
298 | #endif | |
299 | ||
300 | cur_virt_src = (addr64_t)(intptr_t)src; | |
301 | cur_phys_dst = (addr64_t)dst; | |
302 | ||
303 | resid = (unsigned)len; | |
304 | ||
305 | while (resid != 0) { | |
0a7de745 | 306 | if ((cur_phys_src = kdp_vtophys(kernel_pmap, cur_virt_src)) == 0) { |
b0d623f7 | 307 | goto exit; |
0a7de745 | 308 | } |
b0d623f7 A |
309 | |
310 | /* Copy as many bytes as possible without crossing a page */ | |
311 | cnt_src = (unsigned)(PAGE_SIZE - (cur_phys_src & PAGE_MASK)); | |
312 | cnt_dst = (unsigned)(PAGE_SIZE - (cur_phys_dst & PAGE_MASK)); | |
313 | ||
0a7de745 | 314 | if (cnt_src > cnt_dst) { |
b0d623f7 | 315 | cnt = cnt_dst; |
0a7de745 | 316 | } else { |
b0d623f7 | 317 | cnt = cnt_src; |
0a7de745 A |
318 | } |
319 | if (cnt > resid) { | |
b0d623f7 | 320 | cnt = resid; |
0a7de745 | 321 | } |
b0d623f7 | 322 | |
0a7de745 A |
323 | if (EFAULT == ml_copy_phys(cur_phys_src, cur_phys_dst, cnt)) { |
324 | goto exit; /* Copy stuff over */ | |
325 | } | |
326 | cur_virt_src += cnt; | |
327 | cur_phys_dst += cnt; | |
b0d623f7 A |
328 | resid -= cnt; |
329 | } | |
330 | ||
331 | exit: | |
0a7de745 | 332 | return len - resid; |
b0d623f7 A |
333 | } |
334 | ||
335 | int | |
336 | kdp_machine_ioport_read(kdp_readioport_req_t *rq, caddr_t data, uint16_t lcpu) | |
337 | { | |
338 | uint16_t addr = rq->address; | |
339 | uint16_t size = rq->nbytes; | |
340 | ||
341 | if ((lcpu != KDP_CURRENT_LCPU) && (lcpu != cpu_number())) { | |
342 | return (int) kdp_x86_xcpu_invoke(lcpu, (kdp_x86_xcpu_func_t)kdp_machine_ioport_read, rq, data); | |
0a7de745 | 343 | } |
b0d623f7 | 344 | |
0a7de745 | 345 | switch (size) { |
b0d623f7 A |
346 | case 1: |
347 | *((uint8_t *) data) = inb(addr); | |
348 | break; | |
349 | case 2: | |
350 | *((uint16_t *) data) = inw(addr); | |
351 | break; | |
352 | case 4: | |
353 | *((uint32_t *) data) = inl(addr); | |
354 | break; | |
355 | default: | |
356 | return KDPERR_BADFLAVOR; | |
b0d623f7 A |
357 | } |
358 | ||
359 | return KDPERR_NO_ERROR; | |
360 | } | |
361 | ||
362 | int | |
363 | kdp_machine_ioport_write(kdp_writeioport_req_t *rq, caddr_t data, uint16_t lcpu) | |
364 | { | |
365 | uint16_t addr = rq->address; | |
366 | uint16_t size = rq->nbytes; | |
367 | ||
368 | if ((lcpu != KDP_CURRENT_LCPU) && (lcpu != cpu_number())) { | |
369 | return (int) kdp_x86_xcpu_invoke(lcpu, (kdp_x86_xcpu_func_t)kdp_machine_ioport_write, rq, data); | |
370 | } | |
371 | ||
0a7de745 | 372 | switch (size) { |
b0d623f7 A |
373 | case 1: |
374 | outb(addr, *((uint8_t *) data)); | |
375 | break; | |
376 | case 2: | |
377 | outw(addr, *((uint16_t *) data)); | |
378 | break; | |
379 | case 4: | |
380 | outl(addr, *((uint32_t *) data)); | |
381 | break; | |
382 | default: | |
383 | return KDPERR_BADFLAVOR; | |
b0d623f7 A |
384 | } |
385 | ||
386 | return KDPERR_NO_ERROR; | |
387 | } | |
388 | ||
389 | int | |
390 | kdp_machine_msr64_read(kdp_readmsr64_req_t *rq, caddr_t data, uint16_t lcpu) | |
391 | { | |
392 | uint64_t *value = (uint64_t *) data; | |
393 | uint32_t msr = rq->address; | |
394 | ||
395 | if ((lcpu != KDP_CURRENT_LCPU) && (lcpu != cpu_number())) { | |
396 | return (int) kdp_x86_xcpu_invoke(lcpu, (kdp_x86_xcpu_func_t)kdp_machine_msr64_read, rq, data); | |
397 | } | |
398 | ||
399 | *value = rdmsr64(msr); | |
400 | return KDPERR_NO_ERROR; | |
401 | } | |
402 | ||
403 | int | |
404 | kdp_machine_msr64_write(kdp_writemsr64_req_t *rq, caddr_t data, uint16_t lcpu) | |
405 | { | |
406 | uint64_t *value = (uint64_t *) data; | |
407 | uint32_t msr = rq->address; | |
408 | ||
409 | if ((lcpu != KDP_CURRENT_LCPU) && (lcpu != cpu_number())) { | |
410 | return (int) kdp_x86_xcpu_invoke(lcpu, (kdp_x86_xcpu_func_t)kdp_machine_msr64_write, rq, data); | |
411 | } | |
412 | ||
413 | wrmsr64(msr, *value); | |
414 | return KDPERR_NO_ERROR; | |
415 | } | |
7ddcb079 A |
416 | |
417 | pt_entry_t *debugger_ptep; | |
418 | vm_map_offset_t debugger_window_kva; | |
419 | ||
420 | /* Establish a pagetable window that can be remapped on demand. | |
421 | * This is utilized by the debugger to address regions outside | |
422 | * the physical map. | |
423 | */ | |
424 | ||
425 | void | |
0a7de745 A |
426 | kdp_map_debug_pagetable_window(void) |
427 | { | |
7ddcb079 | 428 | vm_map_entry_t e; |
5ba3f43e A |
429 | kern_return_t kr; |
430 | ||
431 | kr = vm_map_find_space(kernel_map, | |
0a7de745 A |
432 | &debugger_window_kva, |
433 | PAGE_SIZE, 0, | |
434 | 0, | |
435 | VM_MAP_KERNEL_FLAGS_NONE, | |
436 | VM_KERN_MEMORY_OSFMK, | |
437 | &e); | |
7ddcb079 A |
438 | |
439 | if (kr != KERN_SUCCESS) { | |
440 | panic("%s: vm_map_find_space failed with %d\n", __FUNCTION__, kr); | |
441 | } | |
442 | ||
443 | vm_map_unlock(kernel_map); | |
444 | ||
445 | debugger_ptep = pmap_pte(kernel_pmap, debugger_window_kva); | |
446 | ||
447 | if (debugger_ptep == NULL) { | |
316670eb | 448 | pmap_expand(kernel_pmap, debugger_window_kva, PMAP_EXPAND_OPTIONS_NONE); |
7ddcb079 A |
449 | debugger_ptep = pmap_pte(kernel_pmap, debugger_window_kva); |
450 | } | |
451 | } | |
316670eb | 452 | |
0a7de745 | 453 | /* initialize kdp_jtag_coredump with data needed for JTAG coredump extraction */ |
3e170ce0 | 454 | |
0a7de745 A |
455 | void |
456 | kdp_jtag_coredump_init(void) | |
457 | { | |
458 | kdp_jtag_coredump.version = (uint64_t) KDP_JTAG_COREDUMP_VERSION_1; | |
459 | kdp_jtag_coredump.kernel_map_start = (uint64_t) kernel_map->min_offset; | |
460 | kdp_jtag_coredump.kernel_map_end = (uint64_t) kernel_map->max_offset; | |
461 | kdp_jtag_coredump.kernel_pmap_pml4 = (uint64_t) kernel_pmap->pm_pml4; | |
462 | kdp_jtag_coredump.pmap_memory_regions = (uint64_t) &pmap_memory_regions; | |
463 | kdp_jtag_coredump.pmap_memory_region_count = (uint64_t) pmap_memory_region_count; | |
464 | kdp_jtag_coredump.pmap_memory_region_t_size = (uint64_t) sizeof(pmap_memory_region_t); | |
465 | kdp_jtag_coredump.physmap_base = (uint64_t) &physmap_base; | |
466 | ||
467 | /* update signature last so that JTAG can trust that structure has valid data */ | |
468 | kdp_jtag_coredump.signature = (uint64_t) KDP_JTAG_COREDUMP_SIGNATURE; | |
469 | } | |
3e170ce0 | 470 | |
0a7de745 A |
471 | void |
472 | kdp_machine_init(void) | |
473 | { | |
474 | if (debug_boot_arg == 0) { | |
475 | return; | |
476 | } | |
477 | ||
478 | kdp_map_debug_pagetable_window(); | |
479 | kdp_jtag_coredump_init(); | |
480 | } |