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 /* 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 33 * services. 34 */ 35 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> 44 #include <sys/trap.h> 45 #include <sys/kobj.h> 46 #include <sys/kobj_impl.h> 47 #include <sys/hypervisor.h> 48 #include <sys/bootconf.h> 49 #include <sys/bootinfo.h> 50 #include <sys/promif.h> 51 #include <sys/evtchn_impl.h> 52 #include <sys/cpu.h> 53 #include <vm/kboot_mmu.h> 54 #include <vm/hat_pte.h> 55 56 static volatile int kdi_slaves_go; 57 58 /* 59 * These are not safe against dropping into kmdb when fbt::: is active. This is 60 * also broken on i86pc... 61 */ 62 63 void 64 kdi_idtr_write(desctbr_t *idtr) 65 { 66 gate_desc_t *idt = (gate_desc_t *)idtr->dtr_base; 67 uint_t nidt = (idtr->dtr_limit + 1) / sizeof (*idt); 68 uint_t vec; 69 70 for (vec = 0; vec < nidt; vec++, idt++) 71 xen_idt_write(idt, vec); 72 } 73 74 void 75 kdi_idt_write(gate_desc_t *gate, uint_t vec) 76 { 77 gate_desc_t *idt = CPU->cpu_m.mcpu_idt; 78 79 /* 80 * See kdi_idtr_set(). 81 */ 82 if (idt != NULL) 83 idt[vec] = *gate; 84 85 xen_idt_write(gate, vec); 86 } 87 88 ulong_t 89 kdi_dreg_get(int reg) 90 { 91 return (__hypercall1(__HYPERVISOR_get_debugreg, (long)reg)); 92 } 93 94 void 95 kdi_dreg_set(int reg, ulong_t value) 96 { 97 (void) __hypercall2(__HYPERVISOR_set_debugreg, (long)reg, value); 98 } 99 100 void 101 kdi_flush_caches(void) 102 { 103 } 104 105 /* 106 * To avoid domains sucking up CPU while sitting in kmdb, we make all the slave 107 * CPUs wait for a wake-up evtchn. The master CPU, meanwhile, sleeps for 108 * console activity. 109 */ 110 111 extern void kdi_slave_entry(void); 112 113 void 114 kdi_stop_slaves(int cpu, int doxc) 115 { 116 if (doxc) 117 kdi_xc_others(cpu, kdi_slave_entry); 118 kdi_slaves_go = 0; 119 } 120 121 void 122 kdi_start_slaves(void) 123 { 124 int c; 125 126 kdi_slaves_go = 1; 127 128 for (c = 0; c < NCPU; c++) { 129 if (cpu[c] == NULL || !(cpu[c]->cpu_flags & CPU_READY)) 130 continue; 131 ec_try_ipi(XC_CPUPOKE_PIL, c); 132 } 133 } 134 135 /*ARGSUSED*/ 136 static int 137 check_slave(void *arg) 138 { 139 return (kdi_slaves_go == 1); 140 } 141 142 void 143 kdi_slave_wait(void) 144 { 145 if (!(cpu[CPU->cpu_id]->cpu_flags & CPU_READY)) 146 return; 147 148 ec_wait_on_ipi(XC_CPUPOKE_PIL, check_slave, NULL); 149 } 150 151 /* 152 * Caution. 153 * These routines are called -extremely- early, during kmdb initialization. 154 * 155 * Many common kernel functions assume that %gs has been initialized, 156 * and fail horribly if it hasn't. At this point, the boot code has 157 * reserved a descriptor for us (KMDBGS_SEL) in it's GDT; arrange for it 158 * to point at a dummy cpu_t, temporarily at least. 159 * 160 * Note that kmdb entry relies on the fake cpu_t having zero cpu_idt/cpu_id. 161 */ 162 163 #if defined(__amd64) 164 165 void * 166 boot_kdi_tmpinit(void) 167 { 168 cpu_t *cpu = kobj_zalloc(sizeof (*cpu), KM_TMP); 169 user_desc_t *bgdt; 170 uint64_t gdtpa; 171 ulong_t ma[1]; 172 173 cpu->cpu_self = cpu; 174 175 /* 176 * (Note that we had better switch to a -new- GDT before 177 * we discard the KM_TMP mappings, or disaster will ensue.) 178 */ 179 bgdt = kobj_zalloc(PAGESIZE, KM_TMP); 180 ASSERT(((uintptr_t)bgdt & PAGEOFFSET) == 0); 181 182 init_boot_gdt(bgdt); 183 184 gdtpa = pfn_to_pa(va_to_pfn(bgdt)); 185 ma[0] = (ulong_t)(pa_to_ma(gdtpa) >> PAGESHIFT); 186 kbm_read_only((uintptr_t)bgdt, gdtpa); 187 if (HYPERVISOR_set_gdt(ma, PAGESIZE / sizeof (user_desc_t))) 188 panic("boot_kdi_tmpinit:HYPERVISOR_set_gdt() failed"); 189 190 load_segment_registers(B64CODE_SEL, 0, 0, B32DATA_SEL); 191 192 /* 193 * Now point %gsbase to our temp cpu structure. 194 */ 195 xen_set_segment_base(SEGBASE_GS_KERNEL, (ulong_t)cpu); 196 return (0); 197 } 198 199 /*ARGSUSED*/ 200 void 201 boot_kdi_tmpfini(void *old) 202 { 203 /* 204 * This breaks, why do we need it anyway? 205 */ 206 #if 0 /* XXPV */ 207 load_segment_registers(B64CODE_SEL, 0, KMDBGS_SEL, B32DATA_SEL); 208 #endif 209 } 210 211 #elif defined(__i386) 212 213 /* 214 * Sigh. We're called before we've initialized the kernels GDT, living 215 * off the hypervisor's default GDT. For kmdb's sake, we switch now to 216 * a GDT that looks like dboot's GDT; very shortly we'll initialize and 217 * switch to the kernel's GDT. 218 */ 219 220 void * 221 boot_kdi_tmpinit(void) 222 { 223 cpu_t *cpu = kobj_zalloc(sizeof (*cpu), KM_TMP); 224 user_desc_t *bgdt; 225 uint64_t gdtpa; 226 ulong_t ma[1]; 227 228 cpu->cpu_self = cpu; 229 230 /* 231 * (Note that we had better switch to a -new- GDT before 232 * we discard the KM_TMP mappings, or disaster will ensue.) 233 */ 234 bgdt = kobj_zalloc(PAGESIZE, KM_TMP); 235 236 ASSERT(((uintptr_t)bgdt & PAGEOFFSET) == 0); 237 gdtpa = pfn_to_pa(va_to_pfn(bgdt)); 238 239 init_boot_gdt(bgdt); 240 241 set_usegd(&bgdt[GDT_BGSTMP], 242 cpu, sizeof (*cpu), SDT_MEMRWA, SEL_KPL, SDP_BYTES, SDP_OP32); 243 244 ma[0] = (ulong_t)(pa_to_ma(gdtpa) >> PAGESHIFT); 245 kbm_read_only((uintptr_t)bgdt, gdtpa); 246 if (HYPERVISOR_set_gdt(ma, PAGESIZE / sizeof (user_desc_t))) 247 panic("boot_kdi_tmpinit:HYPERVISOR_set_gdt() failed"); 248 249 load_segment_registers(B32CODE_SEL, B32DATA_SEL, B32DATA_SEL, 0, 250 KMDBGS_SEL, B32DATA_SEL); 251 return (0); 252 } 253 254 /*ARGSUSED*/ 255 void 256 boot_kdi_tmpfini(void *old) 257 { 258 load_segment_registers(B32CODE_SEL, B32DATA_SEL, B32DATA_SEL, 0, 259 0, B32DATA_SEL); 260 } 261 262 #endif /* __i386 */