4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
25 * Copyright 2018 Joyent, Inc.
29 * Kernel/Debugger Interface (KDI) routines. Called during debugger under
30 * various system states (boot, while running, while the debugger has control).
31 * Functions intended for use while the debugger has control may not grab any
32 * locks or perform any functions that assume the availability of other system
36 #include <sys/systm.h>
37 #include <sys/x86_archext.h>
38 #include <sys/kdi_impl.h>
39 #include <sys/smp_impldefs.h>
40 #include <sys/psm_types.h>
41 #include <sys/segments.h>
42 #include <sys/archsystm.h>
43 #include <sys/controlregs.h>
46 #include <sys/kobj_impl.h>
47 #include <sys/clock_impl.h>
50 kdi_system_claim(void)
54 psm_notifyf(PSM_DEBUG_ENTER
);
58 kdi_system_release(void)
60 psm_notifyf(PSM_DEBUG_EXIT
);
66 kdi_gdt2cpu(uintptr_t gdtbase
)
74 if (gdtbase
== (uintptr_t)cp
->cpu_gdt
)
76 } while ((cp
= cp
->cpu_next
) != cpu_list
);
83 kdi_gdt2gsbase(uintptr_t gdtbase
)
85 return ((uintptr_t)kdi_gdt2cpu(gdtbase
));
90 kdi_get_userlimit(void)
96 kdi_get_cpuinfo(uint_t
*vendorp
, uint_t
*familyp
, uint_t
*modelp
)
102 * CPU doesn't work until the GDT and gs/GSBASE have been set up.
103 * Boot-loaded kmdb will call us well before then, so we have to
104 * find the current cpu_t the hard way.
107 if ((cpu
= kdi_gdt2cpu(gdtr
.dtr_base
)) == NULL
||
108 !cpuid_checkpass(cpu
, 1))
109 return (EAGAIN
); /* cpuid isn't done yet */
111 *vendorp
= cpuid_getvendor(cpu
);
112 *familyp
= cpuid_getfamily(cpu
);
113 *modelp
= cpuid_getmodel(cpu
);
119 kdi_idtr_set(gate_desc_t
*idt
, size_t limit
)
124 * This rare case could happen if we entered kmdb whilst still on the
125 * fake CPU set up by boot_kdi_tmpinit(). We're trying to restore the
126 * kernel's IDT that we saved on entry, but it was from the fake cpu_t
127 * rather than the real IDT (which is still boot's). It's unpleasant,
128 * but we just encode knowledge that it's idt0 we want to restore.
133 CPU
->cpu_m
.mcpu_idt
= idt
;
134 idtr
.dtr_base
= (uintptr_t)idt
;
135 idtr
.dtr_limit
= limit
;
136 kdi_idtr_write(&idtr
);
140 kdi_plat_call(void (*platfn
)(void))
147 * On Intel, most of these are shared between i86*, so this is really an
151 mach_kdi_init(kdi_t
*kdi
)
153 kdi
->kdi_plat_call
= kdi_plat_call
;
154 kdi
->kdi_kmdb_enter
= kmdb_enter
;
155 kdi
->mkdi_activate
= kdi_activate
;
156 kdi
->mkdi_deactivate
= kdi_deactivate
;
157 kdi
->mkdi_idt_switch
= kdi_idt_switch
;
158 kdi
->mkdi_update_drreg
= kdi_update_drreg
;
159 kdi
->mkdi_get_userlimit
= kdi_get_userlimit
;
160 kdi
->mkdi_get_cpuinfo
= kdi_get_cpuinfo
;
161 kdi
->mkdi_stop_slaves
= kdi_stop_slaves
;
162 kdi
->mkdi_start_slaves
= kdi_start_slaves
;
163 kdi
->mkdi_slave_wait
= kdi_slave_wait
;
164 kdi
->mkdi_memrange_add
= kdi_memrange_add
;
165 kdi
->mkdi_reboot
= kdi_reboot
;
169 plat_kdi_init(kdi_t
*kdi
)
171 kdi
->pkdi_system_claim
= kdi_system_claim
;
172 kdi
->pkdi_system_release
= kdi_system_release
;