xref: /titanic_50/usr/src/cmd/mdb/sparc/kmdb/kctl/kctl_isadep.c (revision 22e19ac1a2d512ea8d74e4f3662c08787d0716b1)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/types.h>
29 #include <sys/systm.h>
30 #include <sys/bootconf.h>
31 #include <sys/cpu_module.h>
32 #include <sys/x_call.h>
33 #include <sys/kdi_impl.h>
34 #include <sys/mmu.h>
35 #include <sys/cpuvar.h>
36 #include <sys/kobj.h>
37 #include <sys/kobj_impl.h>
38 #ifdef sun4v
39 #include <sys/ldoms.h>
40 #include <sys/promif_impl.h>
41 #include <kmdb/kmdb_kctl.h>
42 #endif
43 
44 #include <kmdb/kctl/kctl.h>
45 
46 #define	KCTL_TTABLE_SIZE	0x6000	/* trap table size */
47 
48 static uint32_t kctl_trap_brsav;	/* saved ba,a from kmdb_trap */
49 static uint32_t kctl_trap_tl1_brsav;	/* saved ba,a from kmdb_trap_tl1 */
50 
51 extern struct scb trap_table;
52 
53 static void
kctl_patch_text(caddr_t addr,uint32_t data)54 kctl_patch_text(caddr_t addr, uint32_t data)
55 {
56 	if (kctl.kctl_boot_loaded) {
57 		/* LINTED - pointer alignment */
58 		*((uint32_t *)addr) = data;
59 	} else {
60 		hot_patch_kernel_text(addr, data, sizeof (data));
61 	}
62 }
63 
64 /*
65  * The traps that transfer control to kmdb (breakpoint, programmed entry, etc)
66  * use kmdb_trap and kmdb_trap_tl1, which normally begin with a ba,a to
67  * trap_table0 - a bad trap entry.  When kmdb starts, it will use
68  * kctl_ktrap_install to replace the ba with a jmp to the appropriate kmdb
69  * entry points.  Deactivation uses kctl_ktrap_restore to restore the ba
70  * instructions.
71  */
72 static void
kctl_ktrap_install(int tl,void (* handler)(void))73 kctl_ktrap_install(int tl, void (*handler)(void))
74 {
75 	extern uint32_t kmdb_trap, kmdb_trap_tl1;
76 	uint32_t *entryp = tl ? &kmdb_trap_tl1 : &kmdb_trap;
77 	uint32_t *savp = tl ? &kctl_trap_brsav : &kctl_trap_tl1_brsav;
78 	uint32_t hi = (uint32_t)(uintptr_t)handler >> 10;
79 	uint32_t lo = (uint32_t)(uintptr_t)handler & 0x3ff;
80 	uint32_t inst;
81 
82 	*savp = *entryp;
83 
84 	inst = 0x81c06000 | lo; /* jmp %g1 + %lo(handler) */
85 	kctl_patch_text((caddr_t)(entryp + 1), inst);
86 
87 	inst = 0x03000000 | hi;	/* sethi %hi(handler), %g1 */
88 	kctl_patch_text((caddr_t)entryp, inst);
89 }
90 
91 static void
kctl_ktrap_restore(void)92 kctl_ktrap_restore(void)
93 {
94 	extern uint32_t kmdb_trap, kmdb_trap_tl1;
95 
96 	hot_patch_kernel_text((caddr_t)&kmdb_trap, kctl_trap_brsav, 4);
97 	hot_patch_kernel_text((caddr_t)&kmdb_trap_tl1, kctl_trap_tl1_brsav, 4);
98 }
99 
100 static void
kctl_ttable_tlb_modify(caddr_t tba,size_t sz,void (* func)(caddr_t,int))101 kctl_ttable_tlb_modify(caddr_t tba, size_t sz, void (*func)(caddr_t, int))
102 {
103 #if defined(KMDB_TRAPCOUNT)
104 	int do_dtlb = 1;
105 #else
106 	int do_dtlb = 0;
107 #endif
108 
109 	caddr_t va;
110 
111 	ASSERT((sz & MMU_PAGEOFFSET) == 0);
112 
113 	for (va = tba; sz > 0; sz -= MMU_PAGESIZE, va += MMU_PAGESIZE)
114 		func(va, do_dtlb);
115 }
116 
117 static void
kctl_ttable_tlb_lock(caddr_t tba,size_t sz)118 kctl_ttable_tlb_lock(caddr_t tba, size_t sz)
119 {
120 	kctl_ttable_tlb_modify(tba, sz, kdi_tlb_page_lock);
121 }
122 
123 static void
kctl_ttable_tlb_unlock(caddr_t tba,size_t sz)124 kctl_ttable_tlb_unlock(caddr_t tba, size_t sz)
125 {
126 	kctl_ttable_tlb_modify(tba, sz, kdi_tlb_page_unlock);
127 }
128 
129 /*
130  * kmdb has its own trap table.  Life is made considerably easier if
131  * we allocate and configure it here, passing it to the debugger for
132  * final tweaking.
133  *
134  * The debugger code, and data accessed by the handlers are either
135  * a) locked into the TLB or b) accessible by our tte-lookup code.  As
136  * such, we need only lock the trap table itself into the TLBs.  We'll
137  * get the memory for the table from the beginning of the debugger
138  * segment, which has already been allocated.
139  */
140 static void
kctl_ttable_init(void)141 kctl_ttable_init(void)
142 {
143 	xc_all((xcfunc_t *)kctl_ttable_tlb_lock, (uint64_t)kctl.kctl_tba,
144 	    KCTL_TTABLE_SIZE);
145 }
146 
147 static void
kctl_ttable_fini(void)148 kctl_ttable_fini(void)
149 {
150 	xc_all((xcfunc_t *)kctl_ttable_tlb_unlock, (uint64_t)kctl.kctl_dseg,
151 	    KCTL_TTABLE_SIZE);
152 }
153 
154 static caddr_t
kctl_ttable_reserve(kmdb_auxv_t * kav,size_t * szp)155 kctl_ttable_reserve(kmdb_auxv_t *kav, size_t *szp)
156 {
157 	caddr_t tba = kav->kav_dseg;
158 
159 	ASSERT(kav->kav_dseg_size > KCTL_TTABLE_SIZE);
160 	ASSERT(((uintptr_t)kav->kav_dseg & ((1 << 16) - 1)) == 0);
161 
162 	kav->kav_dseg += KCTL_TTABLE_SIZE;
163 	kav->kav_dseg_size -= KCTL_TTABLE_SIZE;
164 
165 	*szp = KCTL_TTABLE_SIZE;
166 	return (tba);
167 }
168 
169 static void
kctl_cpu_init(void)170 kctl_cpu_init(void)
171 {
172 	kctl_ttable_tlb_lock(kctl.kctl_tba, KCTL_TTABLE_SIZE);
173 }
174 
175 int
kctl_preactivate_isadep(void)176 kctl_preactivate_isadep(void)
177 {
178 	if (!kctl.kctl_boot_loaded) {
179 		if (kdi_watchdog_disable() != 0) {
180 			cmn_err(CE_WARN, "hardware watchdog disabled while "
181 			    "debugger is activated");
182 		}
183 
184 		kctl_ttable_init();
185 	}
186 
187 	return (0);
188 }
189 
190 void
kctl_depreactivate_isadep(void)191 kctl_depreactivate_isadep(void)
192 {
193 	kctl_ttable_fini();
194 
195 	kdi_watchdog_restore();
196 }
197 
198 void
kctl_activate_isadep(kdi_debugvec_t * dvec)199 kctl_activate_isadep(kdi_debugvec_t *dvec)
200 {
201 	dvec->dv_kctl_cpu_init = kctl_cpu_init;
202 	dvec->dv_kctl_vmready = kctl_ttable_init;
203 }
204 
205 void
kctl_auxv_init_isadep(kmdb_auxv_t * kav,void * romp)206 kctl_auxv_init_isadep(kmdb_auxv_t *kav, void *romp)
207 {
208 	extern caddr_t boot_tba;
209 	extern void *get_tba(void);
210 	extern int (*cif_handler)(void *);
211 	extern int prom_exit_enter_debugger;
212 
213 	kctl.kctl_tba = kav->kav_tba_native = kctl_ttable_reserve(kav,
214 	    &kav->kav_tba_native_sz);
215 
216 	kav->kav_tba_obp = (boot_tba == NULL ? get_tba() : boot_tba);
217 #ifdef	sun4v
218 	kav->kav_tba_kernel = (caddr_t)&trap_table;
219 #endif
220 	kav->kav_tba_active = (kctl.kctl_boot_loaded ? kav->kav_tba_obp :
221 	    kav->kav_tba_native);
222 
223 	kav->kav_promexitarmp = &prom_exit_enter_debugger;
224 
225 	kav->kav_romp = (kctl.kctl_boot_loaded ? romp : (void *)cif_handler);
226 
227 	kav->kav_ktrap_install = kctl_ktrap_install;
228 	kav->kav_ktrap_restore = kctl_ktrap_restore;
229 #ifdef sun4v
230 	if (kctl.kctl_boot_loaded) {
231 		/*
232 		 * When booting kmdb, kmdb starts before domaining is
233 		 * enabled and before the cif handler is changed to the
234 		 * kernel cif handler. So we start kmdb with using the
235 		 * OBP and we will change this when the cif handler is
236 		 * installed.
237 		 */
238 		kav->kav_domaining = 0;
239 	} else {
240 		kctl_auxv_set_promif(kav);
241 	}
242 #endif
243 }
244 
245 #ifdef sun4v
246 
247 void
kctl_auxv_set_promif(kmdb_auxv_t * kav)248 kctl_auxv_set_promif(kmdb_auxv_t *kav)
249 {
250 	kav->kav_domaining = domaining_enabled();
251 	kav->kav_promif_root = promif_stree_getroot();
252 	kav->kav_promif_in = prom_stdin_ihandle();
253 	kav->kav_promif_out = prom_stdout_ihandle();
254 	kav->kav_promif_pin = prom_stdin_node();
255 	kav->kav_promif_pout = prom_stdout_node();
256 	kav->kav_promif_chosennode = prom_chosennode();
257 	kav->kav_promif_optionsnode = prom_finddevice("/options");
258 }
259 
260 void
kctl_switch_promif(void)261 kctl_switch_promif(void)
262 {
263 	kmdb_auxv_t kav;
264 
265 	kctl_auxv_set_promif(&kav);
266 	kmdb_init_promif(NULL, &kav);
267 }
268 
269 #endif
270 
271 /*ARGSUSED*/
272 void
kctl_auxv_fini_isadep(kmdb_auxv_t * auxv)273 kctl_auxv_fini_isadep(kmdb_auxv_t *auxv)
274 {
275 }
276 
277 void *
kctl_boot_tmpinit(void)278 kctl_boot_tmpinit(void)
279 {
280 	kthread_t *kt0 = kobj_zalloc(sizeof (kthread_t), KM_TMP);
281 	cpu_t *cpu = kobj_zalloc(sizeof (cpu_t), KM_TMP);
282 	kt0->t_cpu = cpu;
283 
284 	return (kctl_curthread_set(kt0));
285 }
286 
287 void
kctl_boot_tmpfini(void * old)288 kctl_boot_tmpfini(void *old)
289 {
290 	(void) kctl_curthread_set(old);
291 }
292