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 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 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 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 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 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 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 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 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 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 170 kctl_cpu_init(void) 171 { 172 kctl_ttable_tlb_lock(kctl.kctl_tba, KCTL_TTABLE_SIZE); 173 } 174 175 int 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 191 kctl_depreactivate_isadep(void) 192 { 193 kctl_ttable_fini(); 194 195 kdi_watchdog_restore(); 196 } 197 198 void 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 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 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 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 273 kctl_auxv_fini_isadep(kmdb_auxv_t *auxv) 274 { 275 } 276 277 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 288 kctl_boot_tmpfini(void *old) 289 { 290 (void) kctl_curthread_set(old); 291 } 292