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